Please consider the following example:
#include <csignal>
class A
{
public:
virtual ~A() {}
virtual void foo() = 0;
};
class B : public A
{
public:
virtual ~B() { throw 5; }
virtual void foo() {}
};
int main(int, char * [])
{
A * b = new B();
try
{
delete b;
}
catch ( ... )
{
raise(SIGTRAP);
}
return 0;
}
I've always thought (naive me) that when the program gets in this case, into catch
section, then object B
at which b
points will be intact because it's quite logical that the exception will have "cancelled" (if programmed safely) the effect of destructor. But when I tried to run this snippet in gdb and got to the breakpoint in catch
section I saw that B object was gone and only A base object left because the vtable looked like this:
(gdb) i vtbl b
vtable for 'A' @ 0x400cf0 (subobject @ 0x603010):
[0]: 0x0
[1]: 0x0
[2]: 0x4008e0 <__cxa_pure_virtual@plt>
My question: is there a way to avoid (half-)destruction of the vtable if I passionately want to throw an exception from a destructor?