Custom C++ Exceptions for Beginners

C++ custom exceptions for beginners

If something goes wrong in a try catch block, an exception automatically gets thrown.

The catch blocks gets the thrown elements.

Throws automatically point the runtime to the closest catch block in the stack.
Usually you use many throws and a few try / catches.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// push elements to a vector
vector<int> myList;
myList.push_back(0); // index 0
myList.push_back(1); // index 1

// try to access the third element which does not exists
try
{
myList.at(2) // index 2
}
catch( exception& e )
{
cout << "Exception happened" << endl;
}

C++ has many exception handling classes that are based on the base exception handling class.

You can listen to only a single type of exception or multiple or even all of them.

1
2
3
4
5
6
7
8
try
{
myList.at(2); // try to access a non existent element
}
catch(...)
{
cout << "Exception happened" << endl;
}

You can throw exceptions with the throw keyword.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double divide ( double a, double b)
{
if ( b == 0 ) // !! Division by zero
throw "Division by zero";
else
return a / b;
}

try
{
double res = divide ( 1, 0);
}
catch ( char* c)
{
cout << c;
}

When to throw

It depends on the application, so there is no easy answer for this but you can follow some guidelines to determine when you should or should not throw.

  • Add preconditions (Did the function actually received the correct arguments)
  • Add postconditions ( Is the values returned by the function correct)

Custom exception class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <exception>

struct MyException : public std::exception
{
const char * what () const throw ()
{
return "C++ Exception";
}
}

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
}
}

More advanced custom exception class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class MyException : public std::exception {
const char* file;
int line;
const char* func;
const char* info;

public:
MyException(const char* msg, const char* file_, int line_, const char* func_, const char* info_ = "") : std::exception(msg),
file (file_),
line (line_),
func (func_),
info (info_)
{
}

const char* get_file() const { return file; }
int get_line() const { return line; }
const char* get_func() const { return func; }
const char* get_info() const { return info; }

}

int main()
{
try
{
some_function()
}
catch (MyException& ex)
{
std::cout << ex.what() << ex.get_info() << std::endl;
std::cout << "Function: " << ex.get_func() << std::endl;
return EXIT_FAILURE;
}

}

Articles