class A
{
public:
void f()
{
vf();
}
virtual void vf()=0;
~A() {;}
};
class B : public A
{
public:
void vf() {;}
}b;
void main()
{
b.~B(); // если убрать вызов деструктора, то разумеется все работает
b.f(); // внутри функции выдается RT-ошибка "pure virtual function is called"
}
Вопрос: как и почему вызов деструктора повлиял на экземпляр b, что внутри вызова b.f(); выдается ошибка
Здравствуйте, <Аноним>, Вы писали:
А>Вопрос: как и почему вызов деструктора повлиял на экземпляр b, что внутри вызова b.f(); выдается ошибка
Ну, во-первых — если формально подходить — очень просто повлиял. Доступ к разрушенному объекту — неопределённое поведение.
А вот типичная реализация этого поведения следующая.
При конструкции/деструкции объекта в момент выполнения тела конструктора/деструктора базового подобъекта, этот подобъект настроен на таблицу виртуальных методов своего — базового — типа.
Поскольку настройка сделана через указатель (vfptr), то перед входом в конструктор/деструктор туда прописывается соответствующий адрес.
B::B()
A::A()
vfptr = &A::vtbl
{
// vfptr == &A::vtbl
// доступны методы A
.....
}
vfptr = B::vtbl
{
// vfptr == &B::vtbl
// доступны методы B
.....
}
// vfptr == &B::vtbl
// доступны методы B
.....
B::~B()
vfptr = B::vtbl
{
// vfptr == &B::vtbl
// доступны методы B
.....
}
A::~A()
vfptr = A::vtbl
{
// vfptr == &A::vtbl
// доступны методы A
.....
}
// vfptr == &A::vtbl
// остался как мусор
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>