I would like to understand what going wrong in the program that cause that PE
which is a derived class, is not catching by the second catch
and display the error like I want.
In the same way, what I have to correct in order to run this simple example
class myEx
{
int errNum;
public:
myEx(int e) : errNum(e) {}
virtual void printErr() { cout << errNum << " "; }
};
class subEx : public myEx
{
string errDesc;
public:
subEx(int e, string d) : myEx(e), errDesc(d) {}
void printErr()
{
myEx::printErr();
cout << errDesc << " ";
}
};
int main()
{
try
{
myEx* pME = new subEx(0, "err 0");
throw pME;
}
catch (myEx* p)
{
p->printErr();
subEx PE(1, "err 1");
throw PE;
}
catch (subEx e)
{
e.printErr();
}
}
A try
block can throw only 1 exception object at a time. It can have multiple catch
blocks to specify different types of exceptions it wants to catch, but only 1 of them will actually be executed at most, the one that most closely matches the type of exception actually thrown.
If no catch
blocks match, the exception propagates the call stack until it finds a higher catch
block that does match.
If a matching catch
block wants to throw a new exception (which is perfectly legal), you need a higher try/catch
to catch it.
Also, do not throw/catch exceptions by pointer. Throw them by value instead, and then catch them by reference. Otherwise, you leak the exception object, as the catch
won't be able to free it correctly when the pointer goes out of scope.
Try this:
class myEx
{
int errNum;
public:
myEx(int e) : errNum(e) {}
virtual void printErr() const
{
cout << errNum << " ";
}
};
class subEx : public myEx
{
string errDesc;
public:
subEx(int e, string d) : myEx(e), errDesc(d) {}
void printErr() const
{
myEx::printErr();
cout << errDesc << " ";
}
};
int main()
{
try
{
try
{
throw subEx(0, "err 0");
}
catch (const myEx &p)
{
p.printErr();
throw subEx(1, "err 1");
}
}
catch (const subEx &e)
{
e.printErr();
}
}