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:
num1
with the value10
andnum2
with the value0
.
- The program initializes two integers:
- Check for division by zero:
- The program uses an
if
condition to check ifnum2
is equal to0
. - If
num2
is0
, athrow
statement is executed to raise an exception with the message"Division by zero error!"
.
- The program uses an
- Handle the exception:
- The program uses a
catch
block to handle the exception. - The
catch
block 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 / num2
is printed usingstd::cout
. - If an exception occurs (as in this case, since
num2
is0
), 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_argument
andstd::runtime_error
.
- Initialize a variable:
- An integer variable
num
is initialized with the value-1
.
- An integer variable
- Check for invalid conditions:
- The program checks if
num
is less than0
using anif
statement. - If the condition is true, a
std::invalid_argument
exception is thrown with the message"Negative number not allowed!"
. - Next, it checks if
num
is equal to0
using anelse if
statement. - If
num
equals0
, astd::runtime_error
exception is thrown with the message"Zero encountered!"
.
- The program checks if
- Handle exceptions:
- The program uses a
try-catch
block to handle exceptions. - The first
catch
block handles exceptions of typestd::invalid_argument
and displays the message"Invalid Argument:"
followed by the exception’s message usinge.what()
. - The second
catch
block handles all other exceptions of typestd::exception
and 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_error
andstd::invalid_argument
where 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 acatch
block.