Exception handling in C++ allows a program to handle runtime errors or exceptional conditions (like dividing by zero, invalid input, or file I/O errors) in a structured and controlled way. Instead of allowing the program to crash when an error occurs, C++ provides a mechanism to detect, report, and recover from exceptions using try, throw, and catch blocks.
The primary components of C++ exception handling are:
try {
// Code that might throw an exception
} catch (type1 e1) {
// Code to handle exception of type type1
} catch (type2 e2) {
// Code to handle exception of type type2
} catch (...) {
// Catch-all block for any exception type
}
try block encloses the code where exceptions might be thrown.catch block is used to catch and handle specific types of exceptions.catch block.Here’s a simple example to demonstrate how exceptions are thrown and caught in C++.
#include <iostream>
using namespace std;
// Function that throws an exception
void testFunction(int number) {
if (number == 0) {
throw "Division by zero error!"; // Throwing an exception
}
cout << "Result: " << 100 / number << endl;
}
int main() {
try {
testFunction(0); // This will throw an exception
} catch (const char* msg) {
cout << "Caught an exception: " << msg << endl; // Handle the exception
}
return 0;
}
testFunction throws an exception if the argument is zero.throw statement is used to raise an exception, and the exception type is specified (const char* in this case).catch block catches the exception and handles it by printing an error message.Output:
Caught an exception: Division by zero error!
Exceptions can be categorized into several types. Common exception types include:
Standard exceptions: C++ provides a set of predefined exception classes in the <stdexcept> header.
std::exception: The base class for all standard exceptions.std::runtime_error: A general exception for runtime errors.std::out_of_range: Thrown when a container or array index is out of bounds.std::invalid_argument: Thrown when an invalid argument is passed to a function.Custom exceptions: You can define your own exception classes by inheriting from std::exception or other exception classes.
You can catch multiple types of exceptions by using multiple catch blocks. C++ will check the exceptions in the order in which they are listed.
#include <iostream>
#include <stdexcept>
using namespace std;
void testFunction(int number) {
if (number == 0) {
throw runtime_error("Runtime error: Division by zero!"); // Throw runtime_error
} else if (number < 0) {
throw invalid_argument("Invalid argument: Negative number!"); // Throw invalid_argument
}
cout << "Result: " << 100 / number << endl;
}
int main() {
try {
testFunction(0); // This will throw a runtime_error
} catch (const runtime_error& e) {
cout << "Caught runtime_error: " << e.what() << endl;
} catch (const invalid_argument& e) {
cout << "Caught invalid_argument: " << e.what() << endl;
}
return 0;
}
testFunction throws a runtime_error if the input is zero and an invalid_argument if the input is negative.catch blocks are used to handle these specific types of exceptions.Output:
Caught runtime_error: Runtime error: Division by zero!
what() MethodThe what() method is defined in the std::exception class. It returns a C-style string (a const char*) that describes the exception.
what() inside a catch block to print an exception's message.what() Method#include <iostream>
#include <stdexcept>
using namespace std;
void testFunction(int number) {
if (number == 0) {
throw runtime_error("Division by zero error!");
}
cout << "Result: " << 100 / number << endl;
}
int main() {
try {
testFunction(0); // This will throw a runtime_error
} catch (const runtime_error& e) {
cout << "Caught an exception: " << e.what() << endl; // Print the exception message
}
return 0;
}
Output:
Caught an exception: Division by zero error!
throw KeywordThe throw keyword is used to throw an exception. You can throw any type of object, but exceptions are often instances of classes derived from std::exception or built-in types like int or char*.
#include <iostream>
using namespace std;
// Custom exception class
class MyException : public exception {
public:
const char* what() const noexcept override {
return "My custom exception occurred!";
}
};
void testFunction(bool throwError) {
if (throwError) {
throw MyException(); // Throw custom exception
}
cout << "No exception occurred!" << endl;
}
int main() {
try {
testFunction(true); // This will throw MyException
} catch (const MyException& e) {
cout << "Caught: " << e.what() << endl; // Handle custom exception
}
return 0;
}
Output:
Caught: My custom exception occurred!
You can have nested try-catch blocks, where one try block is inside another. The inner catch block handles exceptions that occur within the nested try block.
#include <iostream>
using namespace std;
void testFunction() {
try {
cout << "Inside inner try block." << endl;
throw runtime_error("Error occurred in inner block.");
} catch (const runtime_error& e) {
cout << "Caught in inner catch: " << e.what() << endl;
throw; // Rethrow the exception to be caught by outer catch
}
}
int main() {
try {
testFunction(); // Call function that throws an exception
} catch (const runtime_error& e) {
cout << "Caught in outer catch: " << e.what() << endl;
}
return 0;
}
Output:
Inside inner try block.
Caught in inner catch: Error occurred in inner block.
Caught in outer catch: Error occurred in inner block.
Re-throwing an exception is done using the throw keyword without specifying an exception object. This is typically used to catch and log an exception and then pass it along to be handled elsewhere.
#include <iostream>
using namespace std;
void testFunction() {
try {
throw runtime_error("Runtime error in testFunction!");
} catch (const runtime_error& e) {
cout << "Caught exception: " << e.what() << endl;
throw; // Re-throw the exception
}
}
int main() {
try {
testFunction(); // This will re-throw the exception
} catch (const runtime_error& e) {
cout << "Caught in main: " << e.what() << endl;
}
return 0;
}
Output:
Caught exception: Runtime error in testFunction!
Caught in main: Runtime error in testFunction!
std::exception class provides detailed information about the exception.Open this section to load past papers