if I am passing object of derived class, then the derived class catch block should be invoked. But the output says that the exception is caught by the base class. Why?
#include<iostream>
using namespace std;
class Base {};
class Derived: public Base {};
int main()
{
Derived d;
// some other stuff
try {
// Some monitored code
throw d;
}
catch(Base b) {
cout<<"Caught Base Exception";
}
catch(Derived d) { //This catch block is NEVER executed
cout<<"Caught Derived Exception";
}
getchar();
return 0;
}
Catching base and derived classes exceptions in C++ 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.
Explanation: If both base and derived classes are caught as exceptions then catch block of derived class must appear before the base class. If we put base class first then the derived class catch block will never be reached.
If a catch block ends normally, without a throw , the flow of control passes over all other catch blocks associated with the try block. Whenever an exception is thrown and caught, and control is returned outside of the function that threw the exception, stack unwinding takes place.
If both base and derived classes are caught as exceptions, then the catch block of the derived class must appear before the base class.
The standard says (see [except.handle]/4] of the working draft as an example, emphasis mine):
The handlers for a try block are tried in order of appearance. [ Note: This makes it possible to write handlers that can never be executed, for example by placing a handler for a final derived class after a handler for a corresponding unambiguous public base class.
This is exactly what you did in your code.
Therefore I'd say that's the intended behavior, no matter what was your expectations.
Note that you can swap the two handlers to solve the issue.
There is a little to be said about this.
Firstly, it is good practice to catch exceptions by reference instead of value. This prevents slicing of the exception object in the case that it is derived. This is not specific to exceptions but a general feature of inheritance.
A description of this phenomena is discussed here
Also, as pointed out by another answer, if you insist on doing things this way you need to change the order of catches, as a derived class satisfies the base catch block. There is another way of doing this though that uses this property explicitly: Just have the base class catch everything. You can use this unless there is a very specific feature of the derived exception that needs to be treated separately
The catch clauses are checked in order - you get first match, not best match.
So checking the derived type first would catch that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With