0% found this document useful (0 votes)
0 views16 pages

C++ Exception Handling

C++ Exception Handling is a mechanism to manage runtime errors, allowing programs to maintain normal flow despite anomalies. It involves throwing exceptions when errors occur and catching them in designated handlers, with various types of exceptions defined in the std::exception class. The advantages of exception handling include separating error handling from normal code, allowing functions to handle specific exceptions, and grouping error types for better organization.

Uploaded by

noopursakpal1309
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views16 pages

C++ Exception Handling

C++ Exception Handling is a mechanism to manage runtime errors, allowing programs to maintain normal flow despite anomalies. It involves throwing exceptions when errors occur and catching them in designated handlers, with various types of exceptions defined in the std::exception class. The advantages of exception handling include separating error handling from normal code, allowing functions to handle specific exceptions, and grouping error types for better organization.

Uploaded by

noopursakpal1309
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

C++ Exception Handling

Need for this concept in real-life situations


Suppose there is a form that is to be filled by the user, and the form there is
a field called age. This field should contain integers value only, but what if
the user enters a character value in it? In that case, the user will get an error.
He gets this error because the programmer has done exception handling in
the code while making that form. This is where exception handling is used.
So we have to consider all scenarios because users can also enter any
invalid value. Our program should be able to respond to that type of invalid
value scenarios.

Exception Handling in C++ is a process to handle runtime errors.


We perform exception handling so the normal flow of the application
can be maintained even after runtime errors.
In C++, exceptions are runtime anomalies or abnormal conditions that
a program encounters during its execution. The process of handling these
exceptions is called exception handling. Using the exception handling
mechanism, the control from one part of the program where the exception
occurred can be transferred to another part of the code.
In C++, exception is an event or object which is thrown at runtime. All
exceptions are derived from std::exception class. It is a runtime error
which can be handled. If we don't handle the exception, it prints
exception message and terminates the program.
Exception handling is a mechanism that separates code that detects
and handles exceptional circumstances from the rest of your program. Note
that an exceptional circumstance is not necessarily an error.
When a function detects an exceptional situation, you represent this
with an object. This object is called an exception object. In order to
deal with the exceptional situation, you throw the exception. This
passes control, as well as the exception, to a designated block of code in
a direct or indirect caller of the function that threw the exception. This
block of code is called a handler. In a handler, you specify the types of
exceptions that it may process. The C++ run time, together with the
generated code, will pass control to the first appropriate handler that is able
to process the exception thrown. When this happens, an exception is
caught. A handler may rethrow an exception so it can be caught by another
handler.

• Types of exceptions in C++


Synchronous: Exceptions that happen when something goes wrong
because of a mistake in the input data or when the program is not equipped
to handle the current type of data it’s working with, such as dividing a
number by zero.
Asynchronous: Exceptions that are beyond the program’s control, such
as disc failure, keyboard interrupts, etc.

• C++ Exception Classes


In C++ standard exceptions are defined in <exception> class that we can
use inside our programs. The arrangement of parent-child class hierarchy is
shown below:
All the exception classes in C++ are derived from std::exception class. Let's
see the list of C++ common exception classes.
Exception Description
std::exception It is an exception and parent class of all standard
C++ exceptions.
std::logic_failure It is an exception that can be detected by reading
a code.
std::runtime_error It is an exception that cannot be detected by
reading a code.
std::bad_exception It is used to handle the unexpected exceptions in a
c++ program.
std::bad_cast This exception is generally be thrown by
dynamic_cast.
std::bad_typeid This exception is generally be thrown by typeid.
std::bad_alloc This exception is generally be thrown by new.
std::invalid_argument This is thrown due to invalid arguments.
std::length_error This is thrown when a too big std::string is
created.
std::range_error Thi s is occurred when you try to store a value
which is out of range.

• Why do we need Exception Handling in C++?


The following are the main advantages of exception handling over
traditional error handling:

Separation of Error Handling Code from Normal Code: There


are always if-else conditions to handle errors in traditional error handling
codes. These conditions and the code to handle errors get mixed up with the
normal flow. This makes the code less readable and maintainable. With
try/catch blocks, the code for error handling becomes separate from the
normal flow.
Functions/Methods can handle only the exceptions they
choose: A function can throw many exceptions, but may choose to handle
some of them. The other exceptions, which are thrown but not caught, can
be handled by the caller. If the caller chooses not to catch them, then the
exceptions are handled by the caller of the caller.
In C++, a function can specify the exceptions that it throws using the throw
keyword. The caller of this function must handle the exception in some way
(either by specifying it again or catching it).
Grouping of Error Types: In C++, both basic types and objects can be
thrown as exceptions. We can create a hierarchy of exception objects, group
exceptions in namespaces or classes, and categorize them according to their
types.

• C++ Exception Handling Keywords


In C++, we use 3 keywords to perform exception handling:
• try
• catch, and
• throw
The try statement allows you to define a block of code to be tested for
errors while it is being executed. It identifies a block of code for which
particular exceptions will be activated. It's followed by one or more catch
blocks. If an exception occurs, try block throws that exception. You use
a try block to indicate which areas in your program that might throw
exceptions you want to handle immediately. You use a function try block to
indicate that you want to detect exceptions in the entire body of a function.
The throw keyword throws an exception when a problem is detected,
which lets us create a custom error.
The catch statement allows you to define a block of code to be executed,
if an error occurs in the try block.
The try and catch keywords come in pairs
• Syntax of try-catch in C++
try {
// Code that might throw an exception
throw SomeExceptionType("Error message");
}
catch( ExceptionName e1 ) {
// catch block catches the exception that is thrown from try block
}

Assuming a block will raise an exception, a method catches an exception


using a combination of the try and catch keywords. A try/catch block is
placed around the code that might generate an exception. Code within a
try/catch block is referred to as protected code, and the syntax for using
try/catch as follows −

try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
}
catch( ExceptionName e2 ) {
// catch block
}
catch( ExceptionName eN ) {
// catch block
}

You can list down multiple catch statements to catch different type of
exceptions in case your try block raises more than one exception in
different situations.

Throwing Exceptions
Exceptions can be thrown anywhere within a code block
using throw statement. The operand of the throw statement determines a
type for the exception and can be any expression and the type of the result
of the expression determines the type of exception thrown.

Following is an example of throwing an exception when dividing by zero


condition occurs −

double division(int a, int b) {


if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}

Catching Exceptions

The catch block following the try block catches any exception. You can
specify what type of exception you want to catch and this is determined by
the exception declaration that appears in parentheses following the keyword
catch.

try {
// protected code
} catch( ExceptionName e ) {
// code to handle ExceptionName exception
}

Above code will catch an exception of ExceptionName type. If you want


to specify that a catch block should handle any type of exception that is
thrown in a try block, you must put an ellipsis, ..., between the parentheses
enclosing the exception declaration as follows −

try {
// protected code
} catch(...) {
// code to handle any exception
}
The following is an example, which throws a division by zero exception
and we catch it in catch block.
// program to divide two numbers throws an exception when the divisor is 0

#include <iostream>
using namespace std;
int main() {
double numerator, denominator, divide;
cout << "Enter numerator: ";
cin >> numerator;
cout << "Enter denominator: ";
cin >> denominator;
try {
// throw an exception if denominator is 0
if (denominator == 0)
throw 0;
// not executed if denominator is 0
divide = numerator / denominator;
cout << numerator << " / " << denominator << " = " << divide <<
endl;
}
catch (int num_exception) {
cout << "Error: Cannot divide by " << num_exception << endl;
}
return 0;
}

Exception Handling: Prevents program crash due to division by zero.


Throws an Integer Exception (0) when division by zero is attempted.
Catches and Displays an Error Message instead of crashing.
#include <iostream>
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
} catch (const char* msg) {
cerr << msg << endl;
}

return 0;
}

#include <iostream>
#include <stdexcept> // For runtime_error
using namespace std;
int main() {
double numerator, denominator, divide;
cout << "Enter numerator: ";
cin >> numerator;
cout << "Enter denominator: ";
cin >> denominator;
try {
// Throw an exception if denominator is 0
if (denominator == 0)
throw runtime_error("Division by zero is not allowed");
divide = numerator / denominator;
cout << numerator << " / " << denominator << " = " << divide
<< endl;
}
catch (const runtime_error& e) {
cout << "Error: " << e.what() << endl;
}
return 0;
}
Output :
Enter numerator: 10
Enter denominator: 0
ERROR!
Error: Division by zero is not allowed
e.what() in C++ Exception Handling
In C++, e.what() is a member function of the std::exception class (and its
derived classes like std::runtime_error). It returns a descriptive error
message when an exception is thrown. When an exception is caught, calling
e.what() gives us a human-readable string describing the error.

Example:1
#include <iostream>
using namespace std;
int main() {
try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough.";
} else {
throw (age);
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Age is: " << myNum;
}
return 0;
}
Example:2
#include <iostream>
#include <stdexcept> // For standard exception classes
using namespace std;
int main() {
try {
int age;
cout << "Enter your age: ";
if (!(cin >> age)) { // Check if input is non-numeric
throw invalid_argument("Error: Non-numeric input
entered.");
}
if (age < 0) {
throw out_of_range("Error: Age cannot be negative.");
}
if (age < 18) {
throw runtime_error("Access denied - You must be at
least 18 years old.");
}
cout << "Access granted - You are old enough." << endl;
}
catch (const invalid_argument& e) {
cout << "Invalid Input: " << e.what() << endl;
}
catch (const out_of_range& e) {
cout << "Invalid Age: " << e.what() << endl;
}
catch (const runtime_error& e) {
cout << "Restriction: " << e.what() << endl;
}
catch (const exception& e) {
cout << "An unexpected error occurred: " << e.what() <<
endl;
}

return 0;
}
Properties of Exception Handling in C++

1. There is a special catch block called the ‘catch-all’ block,


written as catch(…), that can be used to catch all types of
exceptions.
If you do not know the throw type used in the try block, you can use the
"three dots" syntax (...) inside the catch block, which will handle any type
of exception:

Example
#include <iostream>
using namespace std;
int main() {
try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough.";
} else {
throw 505;
}
}
catch (…) {
cout << "Access denied - You must be at least 18 years old.\n";
}
return 0;
}

2. Implicit type conversion doesn’t happen for primitive types


In the following program, ‘a’ is not implicitly converted to int.
#include <iostream>
using namespace std;

int main()
{
try {
throw ‘a’;
}
catch (int x) {
cout << "Caught " << x;
}
catch (...) {
cout << "Default Exception\n";
}
return 0;
}

3. If an exception is thrown and not caught anywhere, the


program terminates abnormally.
In the following program, a char is thrown, but there is no catch
block to catch the char.
// C++ program to demonstate property 3: If an exception is
// thrown and not caught anywhere, the program terminates
// abnormally in exception handling.
#include <iostream>
using namespace std;

int main()
{
try {
throw 'a';
}
catch (int x) {
cout << "Caught ";
}
return 0;
}
in C++, try/catch blocks can be nested. Also, an exception can be
re-thrown using “throw; “.
// C++ program to demonstrate try/catch blocks can be nested
in C++
#include <iostream>
using namespace std;
int main()
{

// nesting of try/catch
try {
try {
throw 20;
}
catch (int n) {
cout << "Handle Partially ";
throw; // Re-throwing an exception
}
}
catch (int n) {
cout << "Handle remaining ";
}
return 0;
}
When an exception is thrown, all objects created inside the
enclosing try block are destroyed before the control is transferred
to the catch block.
#include <iostream>
using namespace std;

// Define a class named Test


class Test {
public:
// Constructor of Test
Test() { cout << "Constructor of Test " << endl; }
// Destructor of Test
~Test() { cout << "Destructor of Test " << endl; }
};

int main()
{
try {
// Create an object of class Test
Test t1;

// Throw an integer exception with value 10


throw 10;
}
catch (int i) {
// Catch and handle the integer exception
cout << "Caught " << i << endl;
}
}
Output
Constructor of Test
Destructor of Test
Caught 10
Limitations of Exception Handling in C++
The exception handling in C++ also have few limitations:
• Exceptions may break the structure or flow of the code as
multiple invisible exit points are created in the code which
makes the code hard to read and debug.
• If exception handling is not done properly can lead to resource
leaks as well.
• It’s hard to learn how to write Exception code that is safe.
• There is no C++ standard on how to use exception handling,
hence many variations in exception-handling practices exist.

You might also like