Chapter Nineteen: Identifying Exceptions in Base and Derived Classes
If the compiler identifies exceptions in both the base and derived classes in the code, then it will not run the code or give you an output. When you write the code, you need to write an exception handler code in both the base and derived classes, and the exception handler block should be present before the block for the base class.
You may wonder why you need to add the exception handler block of code for the derived class before the base class. If you write the code for the base class before the derived class, the compiler will not reach the exception handler block of code in the derived class. For instance, the program below will give you the output: “Caught Base Exception.”
#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;
}
If you change the order of the exception handler statements in the code above, the compiler can access both the statements easily. The following is a modified program of the above code, but it prints the following output: “Caught Derived Exception.”
#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(Derived d) {
cout<<"Caught Derived Exception";
}
catch(Base b) {
cout<<"Caught Base Exception";
}
getchar();
return 0;
}
In C++, the compiler may throw an error if it catches or goes through the exception handler code in the base class before it looks at the derived class. It will, however, continue to compile the code. Java, another object-oriented programming language, does not throw any exceptions or errors if this happens. Consider the example below. This code returns the following output: “exception Derived has already been caught.”
//filename Main.java
class Base extends Exception {}
class Derived extends Base  {}
public class Main {
public static void main(String args[]) {
try {
throw new Derived();
}
catch(Base b) {}
catch(Derived d) {}
}
}
Differentiating Between Block and Type Conversions
Consider the following code:
#include <iostream>
using namespace std;
int main()
{
try
{
throw 'x';
}
catch(int x)
{
cout << " Caught int " << x;
}
catch(...)
{
cout << "Default catch block";
}
}
The output of this block of code is: “Default catch block.”
In the program above, an exception is thrown by the compiler in the form of a character. There is an exception handler block of code, but this is only to catch an int error in the code. You may think that the compiler will match the character's ASCII code and use the int exception handler to take care of the error, but this is not what happens in C++. Consider the following example where the exception handler code is not called for the object thrown as an error.
#include <iostream>
using namespace std;
class MyExcept1 {};
class MyExcept2
{
public:
// Conversion constructor
MyExcept2 (const MyExcept1 &e )
{
cout << "Conversion constructor called";
}
};
int main()
{
try
{
MyExcept1 myexp1;
throw myexp1;
}
catch(MyExcept2 e2)
{
cout << "Caught MyExcept2 " << endl;
}
catch(... )
{
cout << " Default catch block " << endl;
}
return 0;
}