OOP Chapter 10 Exception Handling
OOP Chapter 10 Exception Handling
Exception Handling
TABLE OF CONTENTS
10 Exception Handling 1
10.1 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . 1
10.2 Exception Handling Constructs (try, catch, throw) 4
10.3 Advantage over Conventional Error Handling . . . 7
10.4 Multiple Exception Handling . . . . . . . . . . . . . . . 11
10.5 Rethrowing Exception . . . . . . . . . . . . . . . . . . . . . 15
10.6 Catching All Exceptions . . . . . . . . . . . . . . . . . . . 17
10.7 Exception with Arguments . . . . . . . . . . . . . . . . . 18
10.8 Exceptions Specification for Function . . . . . . . . . . 20
10.8.1 Dynamic Exception Specification (Deprecated) 20
10.8.2 Noexcept Specification . . . . . . . . . . . . . . . . . 21
10.9 Handling Uncaught and Unexpected Exceptions . 22
10.9.1 Uncaught Exceptions . . . . . . . . . . . . . . . . . . 23
10.9.2 Unexpected Exceptions . . . . . . . . . . . . . . . . 24
i
Chapter 10
Exception Handling
Exception handling provides several advantages over traditional error handling mech-
anisms, including separation of error-handling code from normal code, centralized
error handling, and the ability to propagate errors up the call stack until they are
handled. It promotes cleaner and more maintainable code by allowing developers to
focus on normal program logic and handling unexpected situations separately.
Error handling in C++ refers to the process of managing and responding to runtime
errors or exceptional conditions that may occur during program execution. Unlike
exceptions, which are used to handle exceptional circumstances, error handling typi-
cally involves detecting and responding to expected errors or failures in the program’s
execution. Error handling in C++ can be accomplished through various techniques,
such as return codes, error flags, and assertions. Let’s explore some common methods
of error handling in C++:
1. Return Codes:
Functions in C++ can return special values, known as return codes, to indicate
success or failure. Conventionally, a function returns 0 to indicate success and
a non-zero value to indicate failure.
2
Example:
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
int divide ( int x , int y) {
i f ( y == 0 ) {
r e t u r n −1; // E r r o r : D i v i s i o n by z e r o
}
r e t u r n x / y ; // S u c c e s s
}
i n t main ( ) {
int r e s u l t = divide (10 , 0);
i f ( r e s u l t == −1) {
c e r r << ” E r r o r : D i v i s i o n by z e r o ” <<
endl ;
} else {
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
}
return 0;
}
Output :
E r r o r : D i v i s i o n by z e r o
2. Error Flags:
Functions can set error flags or status variables to indicate errors. The caller
then checks these flags to determine if an error occurred.
Example:
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
b o o l d i v i d e ( i n t x , i n t y , i n t& r e s u l t ) {
i f ( y == 0 ) {
r e t u r n f a l s e ; // E r r o r : D i v i s i o n by z e r o
}
© iamsspoudel
3
r e s u l t = x / y ; // S u c c e s s
return true ;
}
i n t main ( ) {
int result ;
i f ( ! divide (10 , 0 , r e s u l t )) {
c e r r << ” E r r o r : D i v i s i o n by z e r o ” << e n d l ;
} else {
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
}
return 0;
}
Output :
E r r o r : D i v i s i o n by z e r o
3. Assertions:
Assertions are statements that check for conditions that should always be true
during program execution. If an assertion fails, it indicates a programming error
and terminates the program.
Example:
#i n c l u d e <c a s s e r t >
#i n c l u d e <i o s t r e a m >
i n t main ( ) {
int r e s u l t = divide (10 , 0);
s t d : : cout << ” R e s u l t : ” << r e s u l t << s t d : : e n d l ;
return 0;
© iamsspoudel
4
}
Output :
A s s e r t i o n f a i l e d : y != 0
Summary:
Error handling in C++ involves various techniques, including return codes, error
flags, and assertions. Each method has its advantages and use cases, depending on
the nature of the program and the types of errors expected. Proper error handling is
essential for writing reliable and robust C++ programs, ensuring that they gracefully
handle unexpected situations and provide meaningful feedback to users.
Exception handling in C++ revolves around three main constructs: try, catch, and
throw. These constructs provide a structured way to handle runtime errors or excep-
tional conditions that may occur during program execution.
1. try Block: The try block encloses the code that may potentially throw an
exception. It identifies the region of code where exceptions are anticipated.
Syntax:
try {
// Code t h a t may throw an e x c e p t i o n
} c a t c h ( ExceptionType1& e1 ) {
// Handler f o r ExceptionType1
} c a t c h ( ExceptionType2& e2 ) {
// Handler f o r ExceptionType2
} catch ( . . . ) {
© iamsspoudel
5
// Handler f o r any o t h e r e x c e p t i o n s
}
Example:
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( )
{
try {
// Code t h a t may throw an e x c e p t i o n
throw r u n t i m e e r r o r ( ”An e r r o r o c c u r r e d ” ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
// Handle t h e e x c e p t i o n
c e r r << ” E xce pt ion caught : ” << e . what ( ) <<
endl ;
}
return 0;
}
Output :
E x c e p ti on caught : An e r r o r o c c u r r e d
2. catch Block: The catch block is used to catch and handle exceptions thrown
by the corresponding try block. It specifies the type of exception it can handle
and contains the code to handle the exception.
Syntax:
c a t c h ( ExceptionType& e ) {
// Handler f o r t h e e x c e p t i o n
}
Example:
try {
// Code t h a t may throw an e x c e p t i o n
throw r u n t i m e e r r o r ( ”An e r r o r o c c u r r e d ” ) ;
© iamsspoudel
6
} c a t c h ( c o n s t s t d : : r u n t i m e e r r o r& e ) {
// Handle t h e r u n t i m e e r r o r e x c e p t i o n
c e r r << ”Runtime e r r o r caught : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
// Handle o t h e r t y p e s o f e x c e p t i o n s
c e r r << ”Unknown e r r o r caught ” << e n d l ;
}
Syntax:
Example:
try {
// Code t h a t may throw an e x c e p t i o n
int x = 10;
i f ( x > 5)
{
throw ”x i s t oo l a r g e ” ;
}
} c a t c h ( c o n s t ch ar ∗ message )
{
// Handle t h e e x c e p t i o n
c e r r << ” E xce p t ion caught : ”<< message <<e n d l ;
}
Exception handling in C++ allows you to gracefully handle errors, providing a struc-
tured approach to dealing with unexpected situations. It separates error-handling
logic from normal code, making the program more robust and maintainable.
Combined Program:
#i n c l u d e <i o s t r e a m >
© iamsspoudel
7
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
void divide ( i n t a , i n t b) {
i f ( b == 0 ) {
throw i n v a l i d a r g u m e n t ( ” D i v i s i o n by z e r o ! ” ) ;
}
c o u t << a / b << e n d l ;
}
i n t main ( ) {
try {
divide (10 , 0);
} c a t c h ( c o n s t i n v a l i d a r g u m e n t &e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
Caught e x c e p t i o n : D i v i s i o n by z e r o !
Exception handling in C++ offers several advantages over conventional error handling
methods like return codes or error flags.
• Propagating Errors: Exceptions can propagate up the call stack, allowing cen-
tralized error handling.
• Handling Different Types of Errors: Different catch blocks can handle different
types of errors.
© iamsspoudel
8
1. Separation of Concerns:
With exception handling, error-handling code is separated from the main logic
of the program. This separation enhances code readability and maintainability
by isolating error-handling logic in catch blocks.
Example:
Consider a function that reads data from a file. With exception handling, error
handling code is separated from the file reading logic.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
ifstream f i l e ( filename ) ;
i f (! f i l e . is open ()) {
throw r u n t i m e e r r o r ( ” F a i l e d t o open f i l e ” ) ;
}
i n t main ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
E r r o r : F a i l e d t o open f i l e
© iamsspoudel
9
Example:
Multiple functions may call readFile(), and they can all handle exceptions in a
centralized manner.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
ifstream f i l e ( filename ) ;
if (! file ) {
throw r u n t i m e e r r o r ( ” F a i l e d t o open f i l e : ” + f i l e n a m e ) ;
}
// Read and p r o c e s s t he f i l e (dummy rea d f o r d e m o n s t r a t i o n )
string line ;
while ( g e t l i n e ( f i l e , l i n e )) {
cout << l i n e << e n d l ;
}
}
void processData ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
// P r o c e s s t he data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r p r o c e s s i n g data : ” << e . what ( ) << e n d l ;
}
}
© iamsspoudel
10
i n t main ( ) {
try {
processData ( ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n main ( ) : ” << e . what ( ) << e n d l ;
}
return 0;
}
3. Propagation of Errors:
Exceptions can propagate up the call stack until they are caught, allowing er-
rors to be handled at higher levels of abstraction. This propagation mechanism
simplifies error handling and prevents the need for error checks at each inter-
mediate function call.
Example:
If an error occurs in readFile(), the exception can propagate up to the appro-
priate catch block.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
© iamsspoudel
11
// Function t o p r o c e s s t h e f i l e
void p r o c e s s F i l e ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
// P r o c e s s t he f i l e data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r p r o c e s s i n g f i l e : ” << e . what ( ) << e n d l ;
}
}
i n t main ( ) {
try {
processFile ();
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n main ( ) : ” << e . what ( ) << e n d l ;
}
return 0;
}
Multiple exception handling in C++ allows you to handle different types of exceptions
within the same try block. This enables you to provide specialized handling for various
exceptional situations that may arise during program execution. Here’s how multiple
exception handling works:
© iamsspoudel
12
Syntax:
try {
// Code t h a t may throw e x c e p t i o n s
} c a t c h ( ExceptionType1& e1 ) {
// Handler f o r ExceptionType1
} c a t c h ( ExceptionType2& e2 ) {
// Handler f o r ExceptionType2
} catch ( . . . ) {
// D e f a u l t h a n d l e r f o r any o t h e r e x c e p t i o n s
}
In this syntax:
• The try block contains the code that may throw exceptions.
• You can have multiple catch blocks to handle different types of exceptions.
• The ellipsis (...) catches any other exceptions that are not caught by the pre-
ceding catch blocks.
Example:
Let’s demonstrate multiple exception handling with an example where we perform
division and handle specific exceptions for division by zero and other arithmetic errors.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
i n t d i v i d e ( i n t dividend , i n t d i v i s o r ) {
i f ( d i v i s o r == 0 ) {
throw i n v a l i d a r g u m e n t ( ” D i v i s i o n by z e r o ” ) ;
}
return dividend / d i v i s o r ;
}
© iamsspoudel
13
i n t main ( ) {
try {
int r e s u l t = divide (10 , 0);
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
} c a t c h ( c o n s t i n v a l i d a r g u m e n t& e ) {
c e r r << ” I n v a l i d argument : ” << e . what ( )
<< e n d l ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ”Runtime e r r o r : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ”Unknown e r r o r o c c u r r e d ” << e n d l ;
}
return 0;
}
In this example:
• The try block attempts to perform division, which may throw exceptions.
• The first catch block handles std::invalid argument, which occurs if division by
zero is attempted.
• The second catch block handles std::runtime error, which represents other arith-
metic errors.
• The third catch block catches any other unexpected exceptions that may occur.
Example 2
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
// Function t h a t throws d i f f e r e n t t y p e s o f e x c e p t i o n s
void testFunction ( i n t value ) {
i f ( v a l u e == 0 ) {
throw r u n t i m e e r r o r ( ” Runtime e r r o r : v a l u e i s z e r o ” ) ;
© iamsspoudel
14
} e l s e i f ( v a l u e == 1 ) {
throw l o g i c e r r o r ( ” L o g i c e r r o r : v a l u e i s one ” ) ;
} e l s e i f ( v a l u e == 2 ) {
throw i n v a l i d a r g u m e n t ( ” I n v a l i d argument : v a l u e i s two ” ) ;
} else {
cout << ” Value i s ” << v a l u e << e n d l ;
}
}
i n t main ( ) {
i n t values [ ] = {0 , 1 , 2 , 3};
return 0;
}
By utilizing multiple exception handlers, you can provide targeted handling for differ-
ent types of exceptions, enhancing the robustness and reliability of your error handling
mechanism.
© iamsspoudel
15
Syntax:
try {
// Code t h a t may throw e x c e p t i o n s
} c a t c h ( ExceptionType& e ) {
// A d d i t i o n a l p r o c e s s i n g o r l o g g i n g
// Rethrow t h e e x c e p t i o n
throw ;
}
In this syntax:
• The try block contains the code that may throw exceptions.
• The catch block catches the exception and performs additional processing or
logging.
Example:
Let’s illustrate rethrowing an exception with an example where we open a file and
handle file opening errors. If the file cannot be opened, we log an error message and
rethrow the exception for higher-level handling.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
// Function t h a t throws an e x c e p t i o n
v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
© iamsspoudel
16
i f ( f i l e n a m e == ” ”) {
throw r u n t i m e e r r o r ( ” Filename cannot be empty ” ) ;
}
// S i m u l a t i n g f i l e read o p e r a t i o n
cout << ” Reading f i l e : ” << f i l e n a m e << e n d l ;
}
// Function t h a t h a n d l e s th e e x c e p t i o n and r e t h r o w s i t
v o i d p r o c e s s F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
try {
readFile ( filename ) ;
// P r o c e s s t he f i l e data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n p r o c e s s F i l e : ” << e . what ( ) << e n d l ;
throw ; // Rethrow t he caught e x c e p t i o n
}
}
i n t main ( ) {
try {
processFile (””);
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” Caught i n main : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
E r r o r i n p r o c e s s F i l e : Filename cannot be empty
Caught i n main : Filename cannot be empty
© iamsspoudel
17
Catching all exceptions in C++ involves using a catch block that catches any ex-
ception, regardless of its type. This can be achieved by using an ellipsis (...) as the
exception type in the catch block. Catching all exceptions is useful when you want
to provide a generic error-handling mechanism that can handle any unexpected ex-
ception that may occur. Here’s how it works:
Syntax:
try {
// Code t h a t may throw e x c e p t i o n s
} catch ( . . . ) {
// Handler f o r any type o f e x c e p t i o n
}
In this syntax:
• The try block contains the code that may throw exceptions.
• The catch (...) block catches any type of exception that is thrown within the
try block.
Example:
Let’s illustrate catching all exceptions with an example where we attempt to perform
division. We’ll catch any exceptions that may occur during the division operation
using a catch-all block.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
i n t main ( ) {
try {
int dividend = 10;
int divisor = 0;
i f ( d i v i s o r == 0 ) {
throw r u n t i m e e r r o r ( ” D i v i s i o n by z e r o e r r o r ” ) ;
© iamsspoudel
18
int r e s u l t = dividend / d i v i s o r ;
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” Caught a r u n t i m e e r r o r : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ”An unknown e r r o r o c c u r r e d ” << e n d l ;
}
return 0;
}
Catching all exceptions can be useful in scenarios where you want to provide a generic
error-handling mechanism that can handle unexpected errors gracefully. However, it’s
important to use it judiciously, as it may mask specific exceptions and make debugging
more difficult.
In this syntax:
Example:
© iamsspoudel
19
argument when thrown. We’ll use this to demonstrate throwing exceptions with
arguments when a file cannot be opened.
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
#i n c l u d e <s t r i n g >
u s i n g namespace s t d ;
// Custom e x c e p t i o n f o r f i l e opening e r r o r s
c l a s s FileOpenError : public runtime error {
public :
F i l e O p e n E r r o r ( c o n s t s t r i n g& f i l e n a m e )
: r u n t i m e e r r o r ( ” F a i l e d t o open f i l e : ” + f i l e n a m e ) {}
};
// Function t o open a f i l e
v o i d o p e n F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
// S i m u l a t i n g f i l e open f a i l u r e
bool fileOpenFailed = true ;
// Replace with a c t u a l f i l e opening l o g i c
i f ( fileOpenFailed ) {
throw F i l e O p e n E r r o r ( f i l e n a m e ) ;
}
}
i n t main ( ) {
s t r i n g f i l e n a m e = ” example . t x t ” ;
try {
openFile ( filename ) ;
} c a t c h ( c o n s t F i l e O p e n E r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;
© iamsspoudel
20
return 0;
}
Throwing exceptions with arguments allows you to provide detailed information about
errors, making it easier to diagnose and handle them appropriately in the catching
code.
In C++, exception specifications for functions are used to declare the types of excep-
tions that a function may throw. This provides information to callers of the function
about the exceptional situations they need to handle. There are two types of excep-
tion specifications: dynamic and noexcept.
r e t u r n t y p e f u n c t i o n n a m e ( p a r a m e t e r l i s t ) throw ( e x c e p t i o n l i s t ) ;
v o i d f u n c 1 ( ) ; // throw any e x c e p t i o n
v o i d f u n c 2 ( ) throw ; // cannot throw any e x c e p t i o n
v o i d f u n c 3 ( ) throw ( x ) ;
// throw x e x c e p t i o n and e x c e p t i o n d e r i v e d from x
Dynamic exception specifications use the throw() specifier to indicate the types of
exceptions that a function may throw. This is deprecated in modern C++ in favor
of noexcept.
Syntax:
r e t u r n t y p e f u n c t i o n n a m e ( p a r a m e t e r l i s t ) throw ( e x c e p t i o n l i s t ) ;
In this syntax:
© iamsspoudel
21
Example:
v o i d p r o c e s s F i l e ( c o n s t s t d : : s t r i n g& f i l e n a m e )
throw ( r u n t i m e e r r o r )
{
// Code t h a t may throw s t d : : r u n t i m e e r r o r
}
noexcept is a specifier used to declare that a function does not throw any exceptions.
This provides information to the compiler and allows for optimizations. If a function
does throw exceptions, it is best practice to specify which exceptions it may throw
using noexcept(false).
Syntax:
Example:
v o i d p r o c e s s F i l e ( c o n s t s t d : : s t r i n g& f i l e n a m e ) n o e x c e p t {
// Code t h a t does not throw e x c e p t i o n s
}
Example:
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
#i n c l u d e <s t r i n g >
u s i n g namespace s t d ;
© iamsspoudel
22
// S i m u l a t e an e r r o r c o n d i t i o n f o r d e m o n s t r a t i o n
bool errorCondition = true ;
// Replace with a c t u a l e r r o r −c h e c k i n g l o g i c
i f ( errorCondition ) {
throw r u n t i m e e r r o r ( ” F a i l e d t o p r o c e s s f i l e : ” + f i l e n a m e ) ;
}
// P r o c e s s t h e f i l e i f no e r r o r
cout << ” P r o c e s s i n g f i l e : ” << f i l e n a m e << e n d l ;
}
i n t main ( ) {
s t r i n g f i l e n a m e = ” example . t x t ” ;
try {
processFile ( filename ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;
r e t u r n 1 ; // Return non−z e r o t o i n d i c a t e e r r o r
}
return 0;
}
Handling uncaught and unexpected exceptions in C++ is crucial for ensuring robust-
ness and reliability in your programs. Uncaught exceptions occur when an exception
is thrown but not caught by any try-catch block, leading to program termination. Un-
© iamsspoudel
23
expected exceptions refer to exceptions that are thrown in situations not accounted
for in the code. Handling these scenarios gracefully can help prevent abrupt pro-
gram termination and improve user experience. Here’s how to handle uncaught and
unexpected exceptions:
To handle uncaught exceptions, you can set up a global exception handler using
std::set terminate() or std::set unexpected(). These functions allow you to specify
custom handlers to be invoked when an uncaught exception occurs.
Syntax:
#i n c l u d e <i o s t r e a m >
#i n c l u d e <e x c e p t i o n >
#i n c l u d e <c s t d l i b > // f o r a b o r t
u s i n g namespace s t d ;
v o i d myTerminate ( ) {
c o u t << ”Custom t e r m i n a t e h a n d l e r c a l l e d ” << e n d l ;
a b o r t ( ) ; // o r any o t h e r t e r m i n a t i o n f u n c t i o n you p r e f e r
}
v o i d someFunction ( ) {
throw r u n t i m e e r r o r ( ” Oops ! Something went wrong . ” ) ;
}
i n t main ( ) {
s e t t e r m i n a t e ( myTerminate ) ; // Se t custom t e r m i n a t e h a n d l e r
try {
someFunction ( ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” E xce pt ion caught : ” << e . what ( ) << e n d l ;
}
return 0;
© iamsspoudel
24
Unexpected exceptions can be handled using std::unexpected() function. You can set
up a custom unexpected handler using std::set unexpected() to specify the behavior
when an unexpected exception occurs.
Syntax:
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
void dangerousFunction ( ) {
throw r u n t i m e e r r o r ( ” Dangerous f u n c t i o n e n c o u n t e r e d an e r r o r ! ” ) ;
}
i n t main ( ) {
try {
dangerousFunction ( ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ” Caught unexpected e x c e p t i o n ! ” << e n d l ;
}
return 0;
}
Example:
Here’s an example demonstrating how to set up custom handlers for uncaught and
unexpected exceptions:
#i n c l u d e <i o s t r e a m >
© iamsspoudel
25
#i n c l u d e <e x c e p t i o n >
u s i n g namespace s t d ;
v o i d customTerminateHandler ( ) {
c e r r <<”Uncaught e x c e p t i o n d e t e c t e d . Terminating program.”<< e n d l ;
abort ( ) ; // Terminate program f o r c e f u l l y
}
v o i d customUnexpectedHandler ( ) {
c e r r <<”Unexpected e x c e p t i o n d e t e c t e d . Terminating program.”<< e n d l ;
a b o r t ( ) ; // Terminate program f o r c e f u l l y
}
i n t main ( ) {
s e t t e r m i n a t e ( customTerminateHandler ) ;
s e t u n e x p e c t e d ( customUnexpectedHandler ) ;
try {
// Main program l o g i c
throw r u n t i m e e r r o r ( ” Unexpected e r r o r o c c u r r e d ” ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( )
<< e n d l ;
}
return 0;
}
In this example:
• They are set using std::set terminate() and std::set unexpected() before the
main() function.
© iamsspoudel
26
2. What are the advantages of exception handling over conventional error han-
dling? How is multiple exception handling performed in C++ with suitable
example? (3+5)
© iamsspoudel