In this C++ tutorial, in the section titled “Standard exceptions”, there is this example code which uses a class derived from the standard exception class in the STL:
// standard exceptions
#include <iostream>
#include <exception>
using namespace std;
class myexception: public exception
{
virtual const char* what() const throw()
{
return "My exception happened";
}
} myex; //Declares an instance of myexception outside of the main function
int main () {
try
{
throw myex;
}
catch (exception& e) //My question is regarding this line of code
{
cout << e.what() << endl;
}
return 0;
}
That code prints out My exception happened. However, if I remove the ampersand, it prints out std::exception, which is what happens when you call what() with the standard exception class, not the derived class.
The website gives this explanation:
We have placed a handler that catches exception objects by reference
(notice the ampersand & after the type), therefore this catches also
classes derived from exception, like our myex object of class
myexception.
Is throwing myex kind of like “calling a the catch function, and passing myex as a parameter”? Because it that case, I would imagine that it doesn’t matter whether you throw the exception by value or by reference (that’s what the ampersand does right?), because you are still throwing a myexception rather than an exception. And due to dynamic binding and polymorphism or something like that, e.what() should still print out My exception happened rather than std::exception.
This is happening due to object slicing.
If you assign an object of a derived class to an instance of a base class (as in the case of using a copy c’tor when passing by value) all the information of the derived class will be lost (sliced).
For example,
Then if you were to write this:
Then the “someInfo” in
myDerivedInstanceis sliced away inbaseInstance.