<< PreviousNext >>

Answer to Exceptions and inheritance

The correct output is suprisingly:

throw0: unknown
throw1: unknown
throw2: A
throw3: A

Why is it like this? I previously thought that when throwing an exception by reference, the actual type of the exception would be preserved, but that is not the case. Think of throw as a regular function that looks something like this:

template <class T>
void throwException(T t) {
    // ...
}

When we call it, T will be bound to the compile-time type of the variable, which is Exception in the two first cases, and then the object will be copied to the parameter and being sliced in the process. Slicing happens whenever you try to copy a value to a value of a base type. What happens is that any information from the derived type is lost, and the value will be the turned into the base type. So all we have to do is to look at the compile-time type of whatever we pass to throw.

throw2 and throw3 shows how we can do to preserve the actual type of the exception using the throw; statement without a parameter. We also see that the throw; statement does not even have to be in the same function and scope as the corresponding try-catch block. The downside is that if anyone calls your function by mistake (handle in this case), the program will crash.

Another way to do similar things is to use std::exception_ptr, which was introduced in C++11. This allows exceptions to be thrown between threads as well.

Problem

Comments

fedfsem

2017-01-10 07:40 (UTC)

New comment

You can use GitHub flavored markdown here. Parsed by Parsedown, which does not support all of GitHub's features. For example, specifying the language of code listings is not supported.

Name: