Exception Handling in C++
Exception handling in C++ provides a way to manage errors and exceptional circumstances in a program. By using the try, catch, and throw keywords, C++ enables developers to detect, handle, and recover from runtime errors gracefully, ensuring program stability and readability.
Overview of C++ Exception Handling
try: Defines a block of code to test for exceptions.throw: Signals an exception when an error is encountered.catch: Defines a block of code to handle specific exceptions.
Syntax for C++ Exception Handling
</>
Copy
try {
// Code that may throw an exception
throw exception;
} catch (Type1 e1) {
// Handle exception of Type1
} catch (Type2 e2) {
// Handle exception of Type2
}
// Optional: catch-all handler
catch (...) {
// Handle any type of exception
}
Examples of C++ Exception Handling
Example 1: Basic Exception Handling
This example demonstrates the basics of exception handling using try, throw, and catch blocks.
</>
Copy
#include <iostream>
int main() {
try {
int num1 = 10, num2 = 0;
if (num2 == 0)
throw "Division by zero error!";
std::cout << num1 / num2 << std::endl;
} catch (const char* e) {
std::cerr << "Exception caught: " << e << std::endl;
}
return 0;
}
Working of this Program:
- Include necessary headers:
<iostream>: Used for input/output operations.
- Initialize two variables:
- The program initializes two integers:
num1with the value10andnum2with the value0.
- The program initializes two integers:
- Check for division by zero:
- The program uses an
ifcondition to check ifnum2is equal to0. - If
num2is0, athrowstatement is executed to raise an exception with the message"Division by zero error!".
- The program uses an
- Handle the exception:
- The program uses a
catchblock to handle the exception. - The
catchblock captures the exception as aconst char*(a string literal). - The exception message is displayed using
std::cerr, which outputs the error message to the standard error stream.
- The program uses a
- Output the result:
- If no exception occurs, the result of the division
num1 / num2is printed usingstd::cout. - If an exception occurs (as in this case, since
num2is0), the error message"Division by zero error!"is displayed.
- If no exception occurs, the result of the division
Output:
Exception caught: Division by zero error!
Example 2: Handling Multiple Exceptions
This example demonstrates handling multiple types of exceptions.
</>
Copy
#include <iostream>
#include <stdexcept>
int main() {
try {
int num = -1;
if (num < 0)
throw std::invalid_argument("Negative number not allowed!");
else if (num == 0)
throw std::runtime_error("Zero encountered!");
} catch (const std::invalid_argument& e) {
std::cerr << "Invalid Argument: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
Working of this Program:
- Include necessary headers:
<iostream>: Used for input/output operations.<stdexcept>: Provides standard exception classes such asstd::invalid_argumentandstd::runtime_error.
- Initialize a variable:
- An integer variable
numis initialized with the value-1.
- An integer variable
- Check for invalid conditions:
- The program checks if
numis less than0using anifstatement. - If the condition is true, a
std::invalid_argumentexception is thrown with the message"Negative number not allowed!". - Next, it checks if
numis equal to0using anelse ifstatement. - If
numequals0, astd::runtime_errorexception is thrown with the message"Zero encountered!".
- The program checks if
- Handle exceptions:
- The program uses a
try-catchblock to handle exceptions. - The first
catchblock handles exceptions of typestd::invalid_argumentand displays the message"Invalid Argument:"followed by the exception’s message usinge.what(). - The second
catchblock handles all other exceptions of typestd::exceptionand displays the message"Exception:"followed by the exception’s message usinge.what().
- The program uses a
Output:
Invalid Argument: Negative number not allowed!
Best Practices for Exception Handling
- Use exceptions only for exceptional circumstances, not normal control flow.
- Always catch exceptions by reference to avoid slicing.
- Provide meaningful error messages when throwing exceptions.
- Use standard exceptions like
std::runtime_errorandstd::invalid_argumentwhere applicable. - Avoid throwing exceptions in destructors, as they may lead to undefined behavior.
Advanced Topics in Exception Handling
For more complex scenarios, consider these advanced techniques:
- Custom Exception Classes: Define your own exception classes to represent domain-specific errors.
- Exception Safety: Ensure your code adheres to exception safety guarantees, such as strong or basic exception safety.
- Re-throwing Exceptions: Use
throw;to re-throw an exception from acatchblock.
