Exception Handing
Exception Handing
An exception is a problem that arises during the execution of a program. A C++ exception is a response to an
exceptional circumstance that arises while a program is running, such as an attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++ exception handling is built
upon three keywords: try, catch, and throw.
throw − A program throws an exception when a problem shows up. This is done using a throw keyword.
catch − A program catches an exception with an exception handler at the place in a program where you want
to handle the problem. The catch keyword indicates the catching of an exception.
try − A try block identifies a block of code for which particular exceptions will be activated. It's followed by
one or more catch blocks.
Notes
When executing C++ code, different errors can occur: coding errors made by the programmer,
errors due to wrong input, or other unforeseeable things.
When an error occurs, C++ will normally stop and generate an error message. The technical term
for this is: C++ will throw an exception (throw an error).
One of the advantages of C++ over C is Exception Handling. Exceptions are runtime anomalies or abnormal
conditions that a program encounters during its execution.
a) Synchronous
b) Asynchronous
To catch an exception for both base and derive class then we need to put catch block of derived class before the
base class. Otherwise, the catch block of derived class will never be reached.
Exception handling in C++ is done using the try and catch keywords. To catch exceptions, a portion of code is
placed under inspection. This is done by enclosing this portion of code in a try block. When an exception occurs
within the try block, control is transferred to the exception handler.
Exception handling in C++ consists of three keywords: try, throw and catch:
The try statement allows you to define a block of code to be tested for errors while it is being executed.
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.
If no error occurs (e.g. if age is 20 instead of 15, meaning it will be greater than 18), the catch block is skipped.
#include <iostream>
using namespace std;
int main()
{
int x = -1;
// Some code
cout << "Before try \n";
try {
cout << "Inside try \n";
if (x < 0)
{
throw x;
cout << "After throw (Never executed) \n";
}
}
catch (int x ) {
cout << "Exception Caught \n";
}
Output:
Before try
Inside try
Exception Caught
After catch (Will be executed)
The following are the main advantages of exception handling over traditional error handling:
1) Separation of Error Handling code from Normal Code: In traditional error handling codes, there are always if-
else conditions to handle errors. 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.
2) 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.
3) 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++ provides a list of standard exceptions defined in <exception> which we can use in our programs. These are arranged in a
parent-child class hierarchy shown below −
Here is the small description of each exception mentioned in the above hierarchy −
1
std::exception
An exception and parent class of all the standard C++ exceptions.
2
std::bad_alloc
This can be thrown by new.
3
std::bad_cast
This can be thrown by dynamic_cast.
4
std::bad_exception
This is useful device to handle unexpected exceptions in a C++ program.
5
std::bad_typeid
This can be thrown by typeid.
6
std::logic_error
An exception that theoretically can be detected by reading the code.
7
std::domain_error
This is an exception thrown when a mathematically invalid domain is used.
8
std::invalid_argument
This is thrown due to invalid arguments.
9
std::length_error
This is thrown when a too big std::string is created.
10
std::out_of_range
This can be thrown by the 'at' method, for example a std::vector and
std::bitset<>::operator[]().
11
std::runtime_error
An exception that theoretically cannot be detected by reading the code.
12
std::overflow_error
This is thrown if a mathematical overflow occurs.
13
std::range_error
This is occurred when you try to store a value which is out of range.
14
std::underflow_error
This is thrown if a mathematical underflow occurs.
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
Unexpected exception
When a function with an exception specification throws an exception that is not listed in its exception
specification, the C++ run time does the following: The unexpected() function is called. The unexpected() function
calls the function pointed to by unexpected_handler .
std::unexpected() is called by the C++ runtime when a dynamic exception specification is violated: an
exception is thrown from a function whose exception specification forbids exceptions of this type.
std::unexpected() may also be called directly from the program.
In either case, std::unexpected calls the currently installed std::unexpected_handler. The
default std::unexpected_handler calls std::terminate.
Parameters
(none)
Return value
(none)
Exceptions
Throw any exception thrown by the currently installed std::unexpected_handler
C++ Standard Template Library.
In C++, the Standard Template Library (STL) provides a set of programming tools to implement
STL implements these data structures and algorithms using general-purpose classes and functions that
Containers
Iterators
Algorithms
In addition to these, STL also provides several other features, including function objects, smart pointers,
STL containers store data and organize them in a specific manner as required.
For example, vectors store data of the same type in a sequential order. Whereas, maps store data in
key-value pairs.
1. Sequence containers:
Array
Vector
Queue
Deque
Forward_list
List
2. Associative containers:
Set
Multiset
Map
Multimap
Unordered_set
Unordered_multiset
Unordered_map
Unordered_multimap
To learn more about containers, visit our C++ STL Containers tutorial.
Note: STL array is different from the common arrays we've been using so far. STL array is defined in
the std::array class, which contains many useful functions and algorithms in addition to the array data
In C++, vectors are like resizable arrays; they store data of the same type in a sequence and their size
int main() {
return 0;
}
Run Code
Output
1 2 3 4 5
Here, we have created a vector of int type named numbers with 5 elements.
We then used the ranged for loop to print all elements of the vector.
To learn more about vectors in C++, visit our C++ Vectors tutorial.
We can declare an iterator for each container in the C++ Standard Template Library. For example,
vector<int>::iterator it;
We often use iterator member functions like begin(), end(), etc. to return iterators that point to
Here,
numbers.begin() - returns an iterator that points to the beginning of the numbers vector i.e. the
element 3
numbers.end() - returns an iterator that points to the end of the numbers vector.
Note: numbers.end() doesn't return an iterator to the final vector element 4. Instead, it returns an
iterator to the theoretical element that comes after the final element. The same applies to all other
container types.
To learn more about iterators in STL, visit our tutorial on C++ STL Iterators.
int main() {
return 0;
}
Run Code
Output
First Element: 1
Last Element: 5
This is because the end() function points to the theoretical element that comes after the final element
of the container.
So, we need to subtract 1 from numbers.end() in order to point to the final element. Similarly, using the
Note: The asterisk * before itr indicates that the value of the element that the iterator points to is being
// error
cout << itr << " ";
In C++, we can use the Standard Template Library to implement some of the commonly used algorithms.
Some of the most commonly used algorithms in the C++ Standard Template Library are:
Sorting algorithms
Searching algorithms
Copying algorithms
Counting algorithms
To learn more about the algorithms library, visit our C++ STL Algorithms tutorial.
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
return 0;
}
Run Code
Output
1 2 3 4 5
In this example, we have used the sort() function to sort the elements of the numbers vector in
ascending order.
Notice that we have imported the <algorithm> header file to use the sort() function.
C++ Templates
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and
generic functions and thus provides support for generic programming. Generic programming is a
technique where generic types are used as parameters in algorithms so that they can work for a variety
of data types.
o Function templates
o Class templates
Function Templates:
We can define a template for a function. For example, if we have an add() function, we can
create versions of the add function for adding the int, float or double type values.
Class Template:
We can define a template for a class. For example, a class template can be created for the array
class that can accept the array of various types such as int array, float array or double array.
Function Template
o Generic functions use the concept of a function template. Generic functions define a set of
operations that can be applied to the various types of data.
o The type of the data that the function will operate on depends on the type of the data passed as
a parameter.
o For example, Quick sorting algorithm is implemented using a generic function, it can be
implemented to an array of integers or array of floats.
o A Generic function is created by using the keyword template. The template defines what
function will do.
Where Ttype: It is a placeholder name for a data type used by the function. It is used within the
function definition. It is only a placeholder that the compiler will automatically replace this
placeholder with the actual data type.
1. #include <iostream>
2. using namespace std;
3. template<class T> T add(T &a,T &b)
4. {
5. T result = a+b;
6. return result;
7.
8. }
9. int main()
10. {
11. int i =2;
12. int j =3;
13. float m = 2.3;
14. float n = 1.2;
15. cout<<"Addition of i and j is :"<<add(i,j);
16. cout<<'\n';
17. cout<<"Addition of m and n is :"<<add(m,n);
18. return 0;
19. }
Output:
Addition of i and j is :5
Addition of m and n is :3.5
CLASS TEMPLATE
Class Template can also be defined similarly to the Function Template. When a class uses the
concept of Template, then the class is known as generic class.
Syntax
1. template<class Ttype>
2. class class_name
3. {
4. .
5. .
6. }
Ttype is a placeholder name which will be determined when the class is instantiated. We can
define more than one generic data type using a comma-separated list. The Ttype can be used
inside the class body.
1. class_name<type> ob;
type: It is the type of the data that the class is operating on.
1. #include <iostream>
2. using namespace std;
3. template<class T>
4. class A
5. {
6. public:
7. T num1 = 5;
8. T num2 = 6;
9. void add()
10. {
11. std::cout << "Addition of num1 and num2 : " << num1+num2<<std::endl;
12. }
13.
14. };
15.
16. int main()
17. {
18. A<int> d;
19. d.add();
20. return 0;
21. }
Output:
STRING
C++ has in its definition a way to represent a sequence of characters as an object of the class. This
class is called std:: string. The string class stores the characters as a sequence of bytes with the
functionality of allowing access to the single-byte character.
Iterators
Iterator are used to point at the memory addresses of STL containers. They are primarily used in
sequences of numbers, characters etc. They reduce the complexity and execution time of the
program.
Operations of iterators :-
1. begin() :- This function is used to return the beginning position of the container.
2. end() :- This function is used to return the after end position of the container.
3. advance() :- This function is used to increment the iterator position till the specified number mentioned in its
arguments.
4. next() :- This function returns the new iterator that the iterator would point after advancing the
positions mentioned in its arguments.
5. prev() :- This function returns the new iterator that the iterator would point after decrementing the
positions mentioned in its arguments.
6. inserter() :- This function is used to insert the elements at any position in the container. It accepts 2
arguments, the container and iterator to position where the elements have to be inserted.
Types of Iterators :
1. Input Iterators
2. Output Iterators
3. Forward Iterator
4. Bidirectional Iterators
5. Random-Access Iterators
HASH CLASS
The hash class is default constructible, which means that one can construct this object without any
arguments or initialization values. It is used to get the hash value of the argument that is being passed
to it. If the argument doesn’t change, the value doesn’t change either.
Syntax:
IOSTREAM
To perform any input and output operations in C++, we need to use iostream header files.
Without an <iostream> header file, we cannot take input from the user or print any output.
1. #include <iostream.h>
2. #include "iostream.h"
1. Input Stream: To take any input from the user, we need to use cin, which
belongs to the input stream
Syntax to use input stream:
1. std::cin>>variable_name
When the cin is executed, the cursor will be stopped at the particular statement until the value
is entered. The value entered will be stored in a variable.
2. Output Stream: To print the output, we use built-in functions in the cout output stream
1. std::cout<<variable_name
Using cin, we can take input from the user and store the value in the variable. We need to use
the cin keyword followed by >> and the variable name.
Syntax:
1. std::cin>>variable_name
To use cin, we need to use #include <iostream.h> as cin belongs to this header file, and without
this, an error will occur.
Output:
Explanation:
In the above code, we used cin to take the input, so to use cin, we included <iostream.h>
header file. When the input is taken, the string input is stored in the name variable.
2. Cout
To print the output, we need to use the cout keyword, which belongs to the iostream header
file. To use cout, we need to use the cout keyword followed by << and variable or the
statement to print the output.
1. std::cout<<variable_name
1. //to use the cout statement, we need to use the iostream header file
2. #include <iostream.h>
3. using namespace std;
4. int main()
5. {
6. //cout statement is used here to print the statement
7. cout << "Hi from cout statement";
8. return 0;}
Output:
Explanation:
In the above code, we used a cout statement to print the statement. To use the cout statement,
we need to include iostream.h header file. Once the cout is executed, statement or variable
value will be printing the output. To print any statement, we need to use double quotes (" "),
and to print a variable value; we need to use just the variable name without double quotes(" ")
3. Cerr
Cerr is used to print errors in C++, which is present in the iostream header file. If we need to
print any error message in the code if any condition fails, then cerr is very helpful.
1. cerr<<variable_name
Example:
1. #include <iostream>
2. using namespace std;
3. int main() {
4. int a;
5. cin>>a;
6. if(a%2==0){
7. cout<<"The number entered in even number"<<endl;
8. }
9. else{
10. std::cerr << "Enter proper number" << '\n';
11. }
12. return 0;
13. }
Output:
Explanation:
In the above example, we used cin to take the input and check if the given number is even or
not. If the given number is not even, we need to print an error that the given number is not an
even number. We use the cerr keyword in the iostream header file to print this error.
4. Clog:
The clog is also used to print error messages, but unlike cerr, clog is buffered, which means the
error message is stored in a buffer and then will be printed, but cerr is unbuffered and will not
store the error message in the buffer. The clog also belongs to the iostream header file. As the
clog is buffered, it will not show the error message immediately. The clog is preferred more
than cerr when efficiency is more important.
1. clog<<variable_name;
Example:
1. #include <iostream>
2. using namespace std;
3.
4.
5. int main()
6. {
7. clog << "This message is stored in the buffer";
8. return 0;
9. }
Output:
Explanation:
In the above code, we are printing an error. To print this error, we use cerr, which belongs to
the iostream header file. Before printing the error, we store the error in a buffer.
1. #include <iostream>
2. using namespace std;
3.
4. int main()
5. {
6. int a;
7. string b;
8. cin>>a;
9.
10. if(a%2==0){
11. cout<<"The number entered is even number enter a name"<<endl;
12. cin>>b;
13. cout<<b;
14. }
15. else{
16. std::cerr << "Enter even number" << '\n';
17.
18.
19. }
20.
21. }
Output:
Explanation: In the above code, we used all the input and output streams in the iostream.h
header file.