Welcome to The Coding College! In this tutorial, we’ll dive into exceptions in C++, an essential feature for handling runtime errors in a structured and predictable way. Exception handling makes your program more robust and user-friendly by gracefully managing unexpected situations.
What Are Exceptions in C++?
Exceptions are runtime errors or unexpected events that disrupt the normal flow of a program. C++ provides a mechanism to detect and handle such errors using try-catch blocks and the throw
keyword.
Why Use Exception Handling?
- Error Separation: Keeps error-handling code separate from main logic.
- Graceful Recovery: Allows your program to recover and continue running.
- Cleaner Code: Replaces error codes and nested conditionals with structured blocks.
Exception Handling Syntax
try {
// Code that may throw an exception
} catch (type exception) {
// Code to handle the exception
}
Key Components:
try
Block: Code that may throw an exception is wrapped inside thetry
block.throw
Statement: Used to signal an error or exception.catch
Block: Handles the exception. The type of the exception must match the type in thecatch
.
Example: Basic Exception Handling
#include <iostream>
using namespace std;
int main() {
try {
int numerator = 10, denominator = 0;
if (denominator == 0) {
throw "Division by zero error!"; // Throwing an exception
}
cout << "Result: " << numerator / denominator << endl;
} catch (const char* msg) { // Catching the exception
cout << "Exception: " << msg << endl;
}
return 0;
}
Output:
Exception: Division by zero error!
Multiple catch
Blocks
You can use multiple catch
blocks to handle different exception types.
#include <iostream>
using namespace std;
int main() {
try {
int value = -1;
if (value < 0) {
throw value; // Throw an integer exception
}
throw "An unknown error occurred"; // Throw a string exception
} catch (int e) {
cout << "Caught an integer exception: " << e << endl;
} catch (const char* e) {
cout << "Caught a string exception: " << e << endl;
}
return 0;
}
Output:
Caught an integer exception: -1
Catch-All Handler
To handle any exception type, use an ellipsis (...
) in the catch
block.
#include <iostream>
using namespace std;
int main() {
try {
throw 3.14; // Throwing a double exception
} catch (...) {
cout << "Caught an unknown exception!" << endl;
}
return 0;
}
Output:
Caught an unknown exception!
Nested try
Blocks
C++ supports nested try
blocks for localized error handling.
#include <iostream>
using namespace std;
int main() {
try {
try {
throw "Inner exception";
} catch (const char* e) {
cout << "Caught inner exception: " << e << endl;
throw; // Rethrow the exception
}
} catch (...) {
cout << "Caught outer exception!" << endl;
}
return 0;
}
Output:
Caught inner exception: Inner exception
Caught outer exception!
Exception Safety
Always ensure exceptions are handled gracefully without leaking resources. Use RAII (Resource Acquisition Is Initialization) principles to manage resources like memory or file handles.
Using Standard Exceptions
C++ provides a set of standard exceptions in the <stdexcept>
header for common error cases.
Example: Using std::runtime_error
#include <iostream>
#include <stdexcept>
using namespace std;
int main() {
try {
throw runtime_error("This is a runtime error!");
} catch (const runtime_error& e) {
cout << "Exception: " << e.what() << endl;
}
return 0;
}
Output:
Exception: This is a runtime error!
Common Standard Exceptions:
Exception Class | Description |
---|---|
std::exception | Base class for all exceptions. |
std::runtime_error | Errors detected only during program execution. |
std::logic_error | Errors in program logic (e.g., invalid arguments). |
std::out_of_range | Accessing out-of-bounds elements in containers. |
std::bad_alloc | Thrown when memory allocation fails (e.g., new ). |
Custom Exceptions
You can define your own exception classes for more specific error handling.
#include <iostream>
#include <string>
using namespace std;
class MyException : public exception {
string message;
public:
MyException(const string& msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
int main() {
try {
throw MyException("Custom exception occurred!");
} catch (const MyException& e) {
cout << "Exception: " << e.what() << endl;
}
return 0;
}
Output:
Exception: Custom exception occurred!
Summary
- Use try-catch blocks to handle exceptions.
- Use
throw
to signal errors andcatch
to handle them. - Use standard exceptions (
std::exception
) for common error cases. - Create custom exception classes for specific error handling.
- Always ensure resource cleanup, especially in the presence of exceptions.
Learn More at The Coding College
For more tutorials on advanced C++ programming, visit The Coding College.