Пожалуйста, рассмотрите следующий пример:
#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;
}
Я всегда думал (наивно), что, когда программа попадает в этом случае, в раздел catch
, тогда объект B
, в котором точки B
будут неповрежденными, поскольку вполне логично, что исключение будет иметь "отменено" (если запрограммировано безопасно) эффект деструктора. Но когда я попытался запустить этот фрагмент в gdb и попал в точку останова в разделе catch
, я увидел, что объект B ушел, и остался только базовый объект, потому что vtable выглядел так:
(gdb) i vtbl b
vtable for 'A' @ 0x400cf0 (subobject @ 0x603010):
[0]: 0x0
[1]: 0x0
[2]: 0x4008e0 <[email protected]>
Мой вопрос: есть ли способ избежать (половинного) разрушения vtable, если я страстно хочу выбросить исключение из деструктора?