Exceptions are unexpected events that occur during the execution of a program, disrupting the normal flow of execution.
Exception handling allows a program to respond to exceptional circumstances (like runtime errors) in a controlled and graceful manner, preventing abrupt termination.
try {
// Block of code where exceptions might occur
} catch (ExceptionType e) {
// Handler for specific exception type
} catch (...) {
// Default handler for any other exceptions
}
#include
int main() {
try {
int a = 10, b = 0;
if (b == 0)
throw "Division by zero";
std::cout << "Result: " << a / b << std::endl;
} catch (const char* msg) {
std::cerr << "Error: " << msg << std::endl;
}
return 0;
}
// output //
Error: Division by zero
try
block encloses the code that might throw an exception.try
block, we have two integers a
and b
, with b
initialized to 0
.b
is equal to 0
. If it is, we throw a string literal "Division by zero"
.catch
block catches the exception of type const char*
, which is the type of the thrown string literal.catch
block, we print the error message to the standard error stream using std::cerr
.The output is generated because the exception "Division by zero"
is thrown when b
equals 0
, and it’s caught by the catch
block, printing the error message to the standard error stream.
Standard exception classes are predefined exception types provided by the C++ Standard Library. They are designed to cover common types of errors that can occur during program execution. These classes are part of the <stdexcept>
header and are organized in a hierarchical structure.
what()
to retrieve a description of the exception.std::invalid_argument
: Thrown when a function argument is invalid.
std::domain_error
: Thrown when a mathematical function is called with a domain error, such as sqrt(-1).
std::length_error
: Thrown when an attempt is made to exceed the maximum length of a container.
std::out_of_range
: Thrown when an index is out of the allowed range.
std::range_error
: Thrown when a mathematical operation results in a value outside the range representable by the type.
std::overflow_error
: Thrown when an arithmetic overflow occurs during a computation.
std::underflow_error
: Thrown when an arithmetic underflow occurs during a computation.
std::system_error
: Thrown when a system call fails.
#include
#include
int main() {
try {
throw std::runtime_error("Something went wrong!");
} catch (const std::runtime_error& e) {
std::cerr << "Caught a runtime error: " << e.what() << std::endl;
}
return 0;
}
// output //
Caught a runtime error: Something went wrong!
std::runtime_error
, a subclass of std::exception
, to represent a runtime error.std::runtime_error
with the message "Something went wrong!"
inside the try
block.catch
block catches the exception by reference, allowing us to access information about the exception through the e
variable.e.what()
to the standard error stream.Rethrowing allows an exception caught in one part of the program to be thrown again in another part. This is useful when you want to handle an exception at a higher level of the call stack while preserving information about the original exception.
#include
#include
void foo() {
try {
throw std::runtime_error("Error in foo()");
} catch (const std::runtime_error& e) {
std::cerr << "Caught in foo(): " << e.what() << std::endl;
throw; // Rethrow the exception
}
}
int main() {
try {
foo();
} catch (const std::runtime_error& e) {
std::cerr << "Caught in main(): " << e.what() << std::endl;
}
return 0;
}
// output //
Caught in foo(): Error in foo()
Caught in main(): Error in foo()
foo()
function, we throw an instance of std::runtime_error
with the message "Error in foo()"
.foo()
and print a message indicating that it was caught in foo()
.throw;
statement to rethrow the exception.main()
function, we call foo()
inside a try
block and catch any std::runtime_error
exceptions that may occur.foo()
, it’s caught in the catch
block in main()
, and we print a message indicating that it was caught in main()
.While the C++ Standard Library provides a variety of standard exception classes, you may encounter situations where none of these classes precisely fit the error condition you need to represent. In such cases, you can define your own custom exception classes to encapsulate specific error types.
std::exception
or one of its subclasses, such as std::runtime_error
or std::logic_error
.what()
method from the base class to provide a custom error message.
#include
#include
class MyException : public std::exception {
public:
MyException(const std::string& message) : msg(message) {}
const char* what() const noexcept override {
return msg.c_str();
}
private:
std::string msg;
};
int main() {
try {
throw MyException("Custom exception occurred!");
} catch (const MyException& e) {
std::cerr << "Caught a custom exception: " << e.what() << std::endl;
}
return 0;
}
// output //
Caught a custom exception: Custom exception occurred!
MyException
that inherits from std::exception
.MyException
class contains a member variable msg
to store the error message.MyException
that initializes msg
with the provided message.what()
method to return the msg
as a C-style string.main()
function, we throw an instance of MyException
with the message "Custom exception occurred!"
.e
variable, and print it to the standard error stream.std::exception | Base class for all standard C++ exceptions. Provides a what() method to retrieve a description of the exception. |
std::logic_error | Indicates errors in the program’s logic or internal errors detected at compile time. Common subclasses include: std::invalid_argument std::domain_error std::length_error std::out_of_range |
std::runtime_error | Indicates errors detected during runtime that are not related to the program’s logic. Common subclasses include: std::range_error std::overflow_error std::underflow_error std::system_error |
std::invalid_argument | Thrown when a function argument is invalid. |
std::domain_error | Thrown when a mathematical function is called with a domain error, such as sqrt(-1). |
std::length_error | Thrown when an attempt is made to exceed the maximum length of a container. |
std::out_of_range | Thrown when an index is out of the allowed range. |
std::range_error | Thrown when a mathematical operation results in a value outside the range representable by the type. |
std::overflow_error | Thrown when an arithmetic overflow occurs during a computation. |
std::underflow_error | Thrown when an arithmetic underflow occurs during a computation. |
std::system_error | Thrown when a system call fails. |
Exception handling in C++ provides a robust mechanism to deal with unexpected situations in programs. By using try, catch, and throw, you can handle errors gracefully, improving the reliability and maintainability of your code.Happy coding !❤️