In this C++ tutorial, you will learn how try-catch handles exceptions, how to throw an exception, how multiple catch blocks are selected, how to catch any exception with catch (...), and how to rethrow an exception when another part of the program should handle it.
How C++ try-catch handles exceptions
A C++ try-catch statement separates code that may fail from code that handles the failure. Statements that may throw an exception go inside the try block. If an exception is thrown, normal execution of that block stops and C++ looks for a matching catch handler.
If a matching handler is found, that catch block runs. After the handler finishes, execution continues with the statement after the complete try-catch statement. If no matching handler exists in the current function, the exception continues to propagate to an enclosing caller.
Use exceptions for error conditions that a program cannot handle through its normal flow. For simple expected conditions, such as validating input before a calculation, an ordinary if statement may be clearer.
Please note that Try Catch in C++ is quite different, in terms of inbuilt exceptions, from that of in programming languages like Java, Python, etc.
C++ try-catch syntax
Following is the syntax of Try Catch statement.
try {
// statement(s)
} catch (ExceptionName e) {
// statement(s)
}
The try block contains statements that may throw an exception. The catch block specifies the type of exception it can handle and contains the recovery or reporting logic.
When an exception is thrown, statements remaining in the try block are skipped. Control transfers to the first compatible catch block.
C++ try-catch with multiple catch blocks
A single try block can be followed by several catch blocks when different exception types need different handling.
Following is the syntax of try catch statement with multiple catch blocks.
try {
// statement(s)
} catch (ExceptionName1 e) {
// statement(s)
} catch (ExceptionName2 e) {
// statement(s)
} catch (ExceptionName3 e) {
// statement(s)
}
Place more specific handlers before more general handlers. For class-based exceptions, catching by const reference is commonly preferred because it avoids copying the exception object and preserves its dynamic type.
try {
// code that may throw
} catch (const std::invalid_argument& e) {
// handle invalid argument
} catch (const std::exception& e) {
// handle other standard exceptions
}
Throwing an exception in C++
You can throw exception of any primitive datatype or an object of custom class type.
Following is the syntax of throw statement.
throw exception;
In production C++ code, exception objects derived from std::exception, such as std::runtime_error or std::invalid_argument, are usually easier to identify and handle than raw integers or string literals.
C++ try-catch example for division by zero
In this example, we shall try dividing a number with another. Before executing division, we shall check if the denominator is zero and throw an exception if so.
C++ Program
#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 0;
try {
if (b == 0) {
throw 0;
}
cout << a/b << endl;
} catch (int n) {
cout << "Denominator is zero. We cannot perform division." << endl;
}
}
Output
Denominator is zero. We cannot perform division.
Here, b is zero, so throw 0; throws an int. The catch (int n) handler matches that type, prints the message, and prevents the division expression from running.
C++ try-catch with different exception types
In this example, we shall try dividing a number with another. Before executing division, we shall check if the denominator is zero. Throw an exception, if so, of int type. Also, we shall check if numerator is zero and throw an exception of char const* type.
The catch block that matches the thrown exception is executed.
C++ Program
#include <iostream>
using namespace std;
int main() {
int a = 0;
int b = 5;
try {
if (b == 0) {
throw 0;
}
cout << a/b << endl;
if (a/b==0) {
throw "There is nothing to divide among.";
}
} catch (int n) {
cout << "Denominator is zero. We cannot perform division." << endl;
} catch (char const* s) {
cout << s << endl;
}
}
Output
0
There is nothing to divide among.
Because b is not zero, the first handler is not used. The division prints 0, then the string literal is thrown. That value matches the catch (char const* s) handler.
C++ try-catch with std::runtime_error
The following example uses a standard exception type. The program throws std::runtime_error when division cannot be performed and catches it through the base type std::exception.
#include <iostream>
#include <stdexcept>
int main() {
int numerator = 10;
int denominator = 0;
try {
if (denominator == 0) {
throw std::runtime_error("Division by zero is not allowed.");
}
std::cout << numerator / denominator << '\n';
} catch (const std::exception& e) {
std::cout << e.what() << '\n';
}
return 0;
}
Output
Division by zero is not allowed.
The what() member function returns the explanatory message stored in the exception object.
C++ catch all exceptions with catch (…)
C++ provides catch (...) as a catch-all handler. It matches any exception type that was not handled by an earlier catch block.
try {
// code that may throw
} catch (const std::exception& e) {
// handle standard exceptions first
} catch (...) {
// handle any remaining exception type
}
Put catch (...) last. It does not provide direct access to the thrown value, so use a typed handler whenever you need exception-specific information.
Rethrowing an exception from a C++ catch block
A handler can do partial work, such as logging, and then pass the same exception to an outer handler. Use throw; with no operand inside the catch block to rethrow the currently handled exception.
#include <iostream>
#include <stdexcept>
void calculate() {
try {
throw std::runtime_error("Calculation failed.");
} catch (const std::exception& e) {
std::cout << "calculate(): " << e.what() << '\n';
throw;
}
}
int main() {
try {
calculate();
} catch (const std::exception& e) {
std::cout << "main(): " << e.what() << '\n';
}
}
Output
calculate(): Calculation failed.
main(): Calculation failed.
Using throw; preserves the current exception. Throwing a caught object again by name can copy it and may lose derived-type information when it was caught through a base type.
Does C++ try-catch have finally or else?
C++ does not have a built-in finally clause or a Python-style try-else clause. Cleanup is normally handled with automatic objects whose destructors run when a scope is exited, including during exception propagation. This Resource Acquisition Is Initialization (RAII) pattern is used by standard types such as std::vector, smart pointers, file-stream objects, and lock guards.
Code that should run only when the try block succeeds can usually be placed after the statements that may throw, either later in the same try block or after the complete try-catch statement depending on the intended flow.
C++ try-catch rules to remember
- An exception leaves the current
tryblock as soon as it is thrown. - C++ selects the first compatible
catchhandler. - Use specific handlers before general ones.
- For standard and class-based exceptions, prefer catching by
constreference when the handler does not need to modify the exception. - Use
catch (...)last when a true catch-all handler is required. - Use
throw;inside a handler to rethrow the current exception. - C++ has no
finally; use RAII for reliable resource cleanup.
C++ try-catch editorial QA checklist
- Verify that every thrown type has the intended matching
catchhandler. - Check that specific exception handlers appear before broader handlers and before
catch (...). - Confirm that class-based exceptions are caught by
constreference unless copying is intentional. - Check that cleanup is handled by RAII rather than depending on a nonexistent C++
finallyblock. - Verify that rethrow examples use bare
throw;when the same active exception should continue upward.
Summary of C++ try-catch exception handling
In this C++ Tutorial, we learned how a try block runs code that may throw, how matching catch blocks handle exceptions, how to throw standard exception objects, how to catch all exception types, and how to rethrow an exception when it must be handled by another scope.
TutorialKart.com