I want to throw my own exceptions with the base class Exception. There is a virtual method print which will be overwritten by the subclasses. I only catch the type Exception& and use print to get the specific error. The problem is that once I throw a reference of a subclass it is trated as if it were the base class.
Here is an example:
#include <iostream>
using namespace std;
class Exception
{
public:
virtual void print()
{
cout << "Exception" << endl;
}
};
class IllegalArgumentException : public Exception
{
public:
virtual void print()
{
cout << "IllegalArgumentException" << endl;
}
};
int main(int argc, char **argv)
{
try
{
IllegalArgumentException i;
Exception& ref = i;
cout << "ref.print: ";
ref.print();
throw ref;
}
catch(Exception& e)
{
cout << "catched: ";
e.print();
}
}
The output of this example is:
ref.print: IllegalArgumentException
catched: Exception
Using a reference should result in the print method from the derived class being used. Inside the try block the reference does use it. Why doesn’t the catched Exception& act like an IllegalArgumentException and how can I get that behavior?
The following code seems to do what it is supposed to:
try
{
IllegalArgumentException i;
Exception* pointer = &i;
throw pointer;
}
catch(Exception* e)
{
cout << "pointer catched: ";
e->print();
}
but doesn’t the pointer become possibly invalid outside the scope of the try block? It would then be risky to do this and if I allocate memory on the heap to get around that problem I have the responsibility for the deletion inside the catch block which isn’t pretty either. So how would you solve the problem?
throwimplicitly copies, and consequently slices. Quoting C++11, §15.1/3:I’ve seen a handful of codebases that work around this by throwing pointers to exceptions rather than objects directly, but personally I’d just reconsider your “need” to do this in the first place.