Types of Exception in C++

exception handling in c++

Exception handling in C++ is a mechanism that allows a program to detect and respond to unexpected conditions or errors that occur during execution. Instead of terminating the program abruptly, exceptions provide a way to handle errors smoothly and continue program execution if possible.

Basics of Exception Handling

Try, Catch, and Throw

  • try block: Encapsulates the code that might throw an exception.
  • catch block: Captures and handles the exception.
  • throw statement: Signals the occurrence of an exception.

Syntax:

try {

    // Code that may throw an exception

} catch (type exception) {

    // Code to handle the exception

}

throw exception; // To throw an exception

Standard Exceptions

C++ provides a set of standard exceptions defined in the <stdexcept> header. These exceptions cover common error conditions and are derived from the std::exception class.

Common Standard Exceptions

  1. std::exception: Base class for all standard exceptions.
  2. std::runtime_error: Represents errors that occur during program execution.
  3. std::logic_error: Represents errors in the program’s logic.
  4. std::bad_alloc: Thrown when dynamic memory allocation fails.
  5. std::out_of_range: Thrown when an out-of-range access occurs in a container.
  6. std::invalid_argument: Thrown when an invalid argument is passed to a function.

#include <iostream>

#include <stdexcept>

int main() {

    try {

        throw std::runtime_error(“Runtime error occurred”);

    } catch (const std::runtime_error& e) {

        std::cerr << “Caught a runtime_error: ” << e.what() << ‘\n’;

    }

    return 0;

}

User-Defined Exceptions

Developers can define their own exceptions by inheriting from the std::exception class or any of its derived classes. This allows for more specific error handling tailored to the application’s needs.

Example:

#include <iostream>

#include <exception>

class MyException : public std::exception {

public:

    const char* what() const noexcept override {

        return “My custom exception”;

    }

};

int main() {

    try {

        throw MyException();

    } catch (const MyException& e) {

        std::cerr << “Caught MyException: ” << e.what() << ‘\n’;

    }

    return 0;

}

Exception Specifications

Exception specifications in C++ declare which exceptions a function might throw. However, since C++11, the use of dynamic exception specifications is deprecated, and the noexcept keyword is preferred to specify that a function does not throw any exceptions.

Example:

void func() noexcept {

    // This function does not throw exceptions

}

void mayThrow() {

    throw std::runtime_error(“Exception”);

}

int main() {

    try {

        mayThrow();

    } catch (const std::exception& e) {

        std::cerr << “Caught exception: ” << e.what() << ‘\n’;

    }

    return 0;

}

Best Practices for Exception Handling

  1. Use exceptions for exceptional conditions: Do not use exceptions for regular control flow.
  2. Catch exceptions by reference: This avoids slicing and ensures the correct exception type is caught.
  3. Use noexcept where applicable: This helps in optimization and makes the intent clear.
  4. Provide meaningful error messages: Use the what() method to provide useful information about the exception.
  5. Cleanup with RAII: Ensure resources are released properly using Resource Acquisition Is Initialization (RAII).

Conclusion

Exception handling in C++ is a powerful feature that helps in writing robust and maintainable code. By understanding the different types of exceptions and how to handle them effectively, developers can ensure their applications can gracefully handle runtime errors.

Whether using standard exceptions or defining custom ones, following best practices will lead to better error management and improved software quality.

Leave a Reply

Your email address will not be published. Required fields are marked *