For working professionals
For fresh graduates
More
4. C++ Variable
10. C++ for Loop
12. C++ Lambda
13. Loop in C++
15. Array in C++
16. Strings in C++
17. Substring in C++
29. Vector in C++
30. Map in C++
31. Pair in C++
33. Iterators in C++
34. Queue in C++
36. Stack in C++
37. ifstream in C++
40. Templates in C++
43. Namespace in C++
46. Recursion in C++
48. C++ Shell
49. Setw in C++
51. Atoi in C++
54. C# vs C++
55. C++ GUI
56. C++ Game Code
57. Class in C++
58. C++ Header Files
63. Cin in C++
64. Printf in C++
65. Struct in C++
66. C++ List
68. C++ Comments
72. Sorting in C++
Exception handling in C++ is a powerful mechanism that lets us developers manage unexpected events or errors that can occur during program execution. These unexpected events, called exceptions, can disrupt the normal flow of our code and, if left unhandled, lead to crashes, data corruption, or unpredictable behavior.
Let us learn how to deal with any type of C++ exception and handle them gracefully.
We can think of exceptions as alarms that go off when something goes wrong in our program. They signal situations that your code wasn't designed to handle directly. Some common types of exception handling in C++ are:
Robust CPP exception handling is vital for building reliable and user-friendly software:
C++ provides a structured way to detect, handle, and recover from a C++ exception using try-catch blocks, exception throwing, and a hierarchy of exception classes.
The try-catch construct is the heart of C++ exception handling. It consists of two main parts:
Example:
try {
// Code that might throw an exception (e.g., division by zero)
int result = numerator / denominator;
} catch (const std::runtime_error& e) {
// Handle std::runtime_error (e.g., division by zero)
std::cerr << "Error: " << e.what() << std::endl;
} catch (const std::exception& e) {
// Handle any other standard exception
std::cerr << "Error: " << e.what() << std::endl;
}
In the above exception handling in C plus plus example, the code inside the try block is executed and if an exception occurs, the program immediately jumps to the appropriate catch block that matches the exception's type. The code within the matching catch block is executed to handle the exception. If no exception occurs, the catch blocks are skipped.
throw Keyword: The throw keyword is used to manually signal that an exceptional situation has arisen. We throw an object of an exception class to indicate the error when using throw exception C++.
Example:
if (denominator == 0) {
throw std::runtime_error("Division by zero error!");
}
Common scenarios:
C++ provides a hierarchy of standard exception classes:
We can create custom exception classes by deriving them from these standard classes. This allows us to define specialized exception types that better describe our specific error conditions.
This special catch block, written as catch (...), acts as a safety net. It catches any exception that hasn't been caught by the previous, more specific catch blocks. However, we should use it with caution as it can make debugging difficult because we will not know the exact type of exception that occurred.
Here is a C++ exception handling example that you can try out yourself:
#include <iostream>
#include <stdexcept> // For std::runtime_error
double divideNumbers(double numerator, double denominator) {
if (denominator == 0) {
throw std::runtime_error("Error: Division by zero is not allowed.");
}
return numerator / denominator;
}
int main() {
double num1, num2, result;
std::cout << "Enter two numbers: ";
std::cin >> num1 >> num2;
try {
result = divideNumbers(num1, num2);
std::cout << "Result: " << result << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl; // Print the error message
}
return 0;
}
Scenario 1:
#include <iostream>
#include <stdexcept> // For std::runtime_error
double divideNumbers(double numerator, double denominator) {
if (denominator == 0) {
throw std::runtime_error("Error: Division by zero is not allowed.");
}
return numerator / denominator;
}
int main() {
double num1, num2, result;
std::cout << "Enter two numbers: ";
std::cin >> num1 >> num2;
try {
result = divideNumbers(num1, num2);
std::cout << "Result: " << result << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl; // Print the error message
}
return 0;
}
Output:
Enter two numbers: 1 4
Result: 0.25
Scenario 2:
#include <iostream>
#include <stdexcept> // For std::runtime_error
double divideNumbers(double numerator, double denominator) {
if (denominator == 0) {
throw std::runtime_error("Error: Division by zero is not allowed.");
}
return numerator / denominator;
}
int main() {
double num1, num2, result;
std::cout << "Enter two numbers: ";
std::cin >> num1 >> num2;
try {
result = divideNumbers(num1, num2);
std::cout << "Result: " << result << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl; // Print the error message
}
return 0;
}
Output:
Enter two numbers: 1 0
Error: Division by zero is not allowed.
In this C++ exception handling example, the user is asked to input two numbers and the program attempts to divide the numbers using the divideNumbers function.
There are two scenarios in the above exception handling in C++ example:
If you wish to learn how to code in C++, you can check out upGrad’s software engineering courses.
While the basic try-catch mechanism is powerful, C++ offers additional tools for more sophisticated exception handling scenarios.
Exception specifications were a way to declare which exceptions a function might throw.
Example:
void myFunction() throw (std::runtime_error, std::out_of_range) {
// ...
}
This example indicates that myFunction might throw either a std::runtime_error or a std::out_of_range exception. However, exception specifications are now deprecated in modern C++. They had some drawbacks, such as potential performance overhead and unexpected program termination if an unlisted exception was thrown.
We can nest try-catch blocks within each other. This is useful if we have code within an exception handler that might itself throw an exception.
Example:
try {
// Code that might throw an exception
} catch (const std::exception& e) {
try {
// Exception handling code that might also throw
} catch (const std::runtime_error& e2) {
// Handle the nested exception
}
}
Some compilers offer a finally block as an extension. Code within a finally block always executes, regardless of whether an exception was thrown or not. It is useful for cleanup tasks that must happen even if an error occurs. The finally block is not part of standard C++, so its availability and behavior might vary between compilers.
Example:
try {
// ...
} catch (...) {
// ...
} finally {
// Cleanup code (e.g., close files, release resources)
}
When an exception is thrown, the program execution jumps to the nearest suitable catch block. During this process, the function call stack is "unwound." This means:
If we are not careful, stack unwinding can lead to resource leaks. Suppose a function opens a file and throws an exception before closing it. If we do not have proper exception handling, the file might remain open. To prevent this, consider using techniques like RAII (Resource Acquisition Is Initialization) to ensure resources are automatically released when they go out of scope.
In essence, exception handling is like having a safety net for our C++ programs. It allows us to anticipate potential problems, react to them intelligently, and keep your software running smoothly.
If you wish to learn programming languages such as C++, you can check out upGrad’s computer science programs such as the Master’s in Computer Science Program.
If I were to explain exception handling in C++ in a single sentence, I would define it as a mechanism that allows us to gracefully handle unexpected errors or events during program execution, preventing crashes and enabling recovery strategies.
Exception handling in C++ uses try-catch blocks to monitor for errors, allowing the program to gracefully handle unexpected events without crashing.
The syntax involves a try block to enclose code that might throw exceptions, followed by one or more catch blocks to handle specific types of exceptions.
Yes, you can create your own custom exception classes by inheriting from standard C++ exception classes.
Error handling is essential to prevent crashes, provide informative feedback, and ensure your program behaves predictably in unexpected situations.
You should use exception handling in C++ when you anticipate potential errors that could disrupt your program's normal flow, such as invalid input, resource failures, or logic errors.
Exception handling in C++ can have a slight performance overhead, but it's generally considered a worthwhile tradeoff for robustness and maintainability in most cases.
There are two main types of exception handling in C++, synchronous exception handling and asynchronous exception handling.
Author
Start Learning For Free
Explore Our Free Software Tutorials and Elevate your Career.
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.