Module 5 C++
Module 5 C++
divide_by_zero = 7 / 0;
In C++, we handle exceptions with the help of the try and catch blocks, along
with the throw keyword.
· try - code that may raise an exception
· throw - throws an exception when an error is detected
· catch - code that handles the exception thrown by the throw keyword
try {
Here, we have placed the code that might generate an exception inside
the try block. Every try block is followed by the catch block.
When an exception occurs, the throw statement throws an exception, which
is caught by the catch block.
The catch block cannot be used without the try block.
#include <iostream>
using namespace std;
int main() {
try {
return 0;
}
Run Code
Output 1
Enter numerator: 72
Enter denominator: 0
Error: Cannot divide by 0
Output 2
Enter numerator: 72
Enter denominator: 3
72 / 3 = 24
The above program divides two numbers and displays the result. But an
exception occurs if the denominator is 0.
To handle the exception, we have put the code divide = numerator /
denominator; inside the try block. Now, when an exception occurs, the rest of
the code inside the try block is skipped.
The catch block catches the thrown exception and executes the statements
inside it.
If none of the statements in the try block generates an exception,
the catch block is skipped.
Working of try, throw, and catch statements in C++
Notice that we have thrown the int literal 0 with the code throw 0;.
We can throw any literal or variable or class, depending on the situation
and depending on what we want to execute inside the catch block.
The catch parameter int num_exception takes the value passed by
the throw statement i.e. the literal 0.
try {
// code
}
catch (...) {
// code
}
try {
// code
}
catch (exception1) {
// code
}
catch (exception2) {
// code
}
catch (...) {
// code
}
Here, our program catches exception1 if that exception occurs. If not, it will
catch exception2 if it occurs.
If there is an error that is neither exception1 nor exception2, then the code
inside of catch (...) {} is executed.
Notes:
· catch (...) {} should always be the final block in our try...catch statement.
This is because this block catches all possible exceptions and acts
as the default catch block.
· It is not compulsory to include the default catch block in our code.
Example 2: C++ Multiple catch Statements
This program divides two numbers and stores the result in an array
element. There are two possible exceptions that can occur in this program:
· If the array is out of bounds i.e. if the index of the array is greater
than the size of the array
· If a number is divided by 0
These exceptions are caught in multiple catch statements.
#include <iostream>
using namespace std;
int main() {
try {
return 0;
}
Run Code
Output 1
Here, the array arr only has 4 elements. So, index cannot be greater than 3.
In this case, index is 5. So we throw a string literal "Error: Array out of bounds!".
This exception is caught by the first catch block.
Notice the catch parameter const char* msg. This indicates that
the catch statement takes a string literal as an argument.
Output 2
Exception Description
1. try in C++
The try keyword represents a block of code that may throw an exception
placed inside the try block. It’s followed by one or more catch blocks. If an
exception occurs, try block throws that exception.
2. catch in C++
The catch statement represents a block of code that is executed when a
particular exception is thrown from the try block. The code to handle the
exception is written inside the catch block.
3. throw in C++
An exception in C++ can be thrown using the throw keyword. When a
program encounters a throw statement, then it immediately terminates the
current function and starts finding a matching catch block to handle the
thrown exception.
Note: Multiple catch statements can be used to catch different type of
exceptions thrown by try block.
The try and catch keywords come in pairs: We use the try block to test some
code and If the code throws an exception we will handle it in our catch block.
Why do we need Exception Handling in C++?
The following are the main advantages of exception handling over traditional
error handling:
1. 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.
#include <iostream>
#include <stdexcept>
using namespace std;
int main()
{
// try block
try {
int numerator = 10;
int denominator = 0;
int res;
return 0;
}
Output
Exception Division by zero not allowed!
Example 2
The following is a simple example to show exception handling in C++. The
output of the program explains the flow of execution of try/catch blocks.
· CPP
#include <iostream>
using namespace std;
int main()
{
int x = -1;
// Some code
cout << "Before try \n";
// try block
try {
cout << "Inside try \n";
if (x < 0) {
// throwing an exception
throw x;
cout << "After throw (Never executed) \n";
}
}
// catch block
catch (int x) {
cout << "Exception Caught \n";
}
Output
Before try
Inside try
Exception Caught
After catch (Will be executed)
#include <iostream>
using namespace std;
int main()
{
// try block
try {
// throw
throw 10;
}
// catch block
catch (char* excp) {
cout << "Caught " << excp;
}
// catch all
catch (...) {
cout << "Default Exception\n";
}
return 0;
}
Output
Default Exception
Property 2
Implicit type conversion doesn’t happen for primitive types.
Example
In the following program, ‘a’ is not implicitly converted to int.
· CPP
#include <iostream>
using namespace std;
int main()
{
try {
throw 'a';
}
catch (int x) {
cout << "Caught " << x;
}
catch (...) {
cout << "Default Exception\n";
}
return 0;
}
Output
Default Exception
Output:
Default Exception
Property 3
If an exception is thrown and not caught anywhere, the program
terminates abnormally.
Example
In the following program, a char is thrown, but there is no catch block to catch
the char.
· CPP
#include <iostream>
using namespace std;
int main()
{
try {
throw 'a';
}
catch (int x) {
cout << "Caught ";
}
return 0;
}
Output
terminate called after throwing an instance of 'char'
We can change this abnormal termination behavior by writing our
unexpected function.
Note: A derived class exception should be caught before a base class
exception.
Like Java, the C++ library has a standard exception class which is the base
class for all standard exceptions. All objects thrown by the components of
the standard library are derived from this class. Therefore, all standard
exceptions can be caught by catching this type.
Property 4
Unlike Java, in C++, all exceptions are unchecked, i.e., the compiler
doesn’t check whether an exception is caught or not (See this for
details). So, it is not necessary to specify all uncaught exceptions in a
function declaration. However,exception-handling it’s a recommended
practice to do so.
Example
The following program compiles fine, but ideally, the signature of fun() should
list the unchecked exceptions.
· CPP
#include <iostream>
using namespace std;
int main()
{
try {
fun(NULL, 0);
}
catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}
Output
Caught exception from fun()
#include <iostream>
using namespace std;
int main()
{
try {
fun(NULL, 0);
}
catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}
Output
Caught exception from fun()
#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;
}
Output
Handle Partially Handle remaining
A function can also re-throw a function using the same “throw; ” syntax. A
function can handle a part and ask the caller to handle the remaining.
Property 6
When an exception is thrown, all objects created inside the enclosing
try block are destroyed before the control is transferred to the catch
block.
Example
The following program demonstrates the above property.
· CPP
#include <iostream>
using namespace std;
int main()
{
try {
// Create an object of class Test
Test t1;
Output
Constructor of Test
Destructor of Test
Caught 10