Standard Exception Classes in C++
C++ provides a rich set of exception handling mechanisms that allow developers to manage errors during program execution. One of the most important features of C++'s exception handling system is the standard exception classes. These classes are part of the C++ Standard Library and are designed to handle a wide range of common error conditions. In this article, we will explore the standard exception classes available in C++ and how they can be used for effective error handling.
Overview of Standard Exception Classes
The C++ Standard Library provides a base class for exceptions called std::exception
. This base class has several derived classes that represent specific types of errors. These exceptions can be caught using a catch
block, allowing the program to react to various error situations in a structured way. Some of the most commonly used exception classes are:
std::exception
- The base class for all exceptions.std::logic_error
- Used to report errors in the logic of the program.std::runtime_error
- Represents errors that occur during program execution.std::out_of_range
- Used when an argument is out of the expected range.std::invalid_argument
- Thrown when an invalid argument is provided to a function.std::overflow_error
- Used when an arithmetic operation causes overflow.std::underflow_error
- Thrown when an arithmetic operation causes underflow.
Base Class: std::exception
The std::exception
class is the base class for all exceptions in C++. It provides a virtual method what()
that returns a description of the exception. This method can be overridden by derived classes to provide more specific error information.
Example: Using std::exception
#include <iostream> #include <exception> int main() { try { throw std::exception(); // Throw a base class exception } catch (const std::exception& e) { std::cout << "Caught exception: " << e.what() << "\n"; } return 0; }
Output:
Caught exception: std::exception
In this example, the base std::exception
is thrown, and the what()
method returns the string "std::exception" as the description of the error.
std::logic_error
Class
The std::logic_error
class is a subclass of std::exception
used for exceptions that indicate a logical error in the program. These errors usually occur when there is a flaw in the program's logic, such as a violation of preconditions or invariants.
Example: Using std::logic_error
#include <iostream> #include <stdexcept> void testFunction(int a) { if (a == 0) { throw std::logic_error("Zero is not a valid value for a"); } } int main() { try { testFunction(0); // This will throw a logic_error } catch (const std::logic_error& e) { std::cout << "Caught exception: " << e.what() << "\n"; } return 0; }
Output:
Caught exception: Zero is not a valid value for a
In this example, the function throws a std::logic_error
when the input value is 0, which is an invalid value in this case.
std::runtime_error
Class
The std::runtime_error
class is another subclass of std::exception
, and it is used for errors that occur during the execution of the program. These are typically errors that are not predictable at compile time and can only be detected during runtime.
Example: Using std::runtime_error
#include <iostream> #include <stdexcept> void divide(int a, int b) { if (b == 0) { throw std::runtime_error("Division by zero error"); } std::cout << "Result: " << a / b << "\n"; } int main() { try { divide(10, 0); // This will throw a runtime_error } catch (const std::runtime_error& e) { std::cout << "Caught exception: " << e.what() << "\n"; } return 0; }
Output:
Caught exception: Division by zero error
This example demonstrates the use of std::runtime_error
to signal a division by zero error. The exception is thrown when the second argument is zero.
std::out_of_range
Class
The std::out_of_range
class is used to indicate that an operation has attempted to access an element outside the valid range, such as accessing an out-of-bounds index in a container.
Example: Using std::out_of_range
#include <iostream> #include <stdexcept> #include <vector> int main() { try { std::vectorvec = {1, 2, 3}; std::cout << vec.at(5) << "\n"; // This will throw an out_of_range exception } catch (const std::out_of_range& e) { std::cout << "Caught exception: " << e.what() << "\n"; } return 0; }
Output:
Caught exception: vector::at: index out of range
Here, the std::out_of_range
exception is thrown when trying to access an invalid index in the vector using the at()
method.
std::invalid_argument
Class
The std::invalid_argument
class is used when a function receives an invalid argument. This exception is thrown when the input argument is not appropriate for the function, but it doesn't necessarily violate the program's logic.
Example: Using std::invalid_argument
#include <iostream> #include <stdexcept> void testFunction(int a) { if (a < 0) { throw std::invalid_argument("Negative value is not allowed"); } } int main() { try { testFunction(-1); // This will throw an invalid_argument exception } catch (const std::invalid_argument& e) { std::cout << "Caught exception: " << e.what() << "\n"; } return 0; }
Output:
Caught exception: Negative value is not allowed
In this example, the function throws a std::invalid_argument
exception when the input is a negative number.
Conclusion
The standard exception classes in C++ provide a flexible and structured way to handle errors that occur during program execution. By using these built-in exceptions, such as std::exception
, std::logic_error
, std::runtime_error
, and others, you can handle a wide range of error conditions effectively. Properly utilizing these exception classes helps you write more robust and maintainable C++ programs that can react to unexpected situations gracefully.