Любопытная RT-ошибка "pure virtual function is called"
От: Аноним  
Дата: 17.11.09 09:56
Оценка: :))) :))) :))) :)
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(); выдается ошибка
Re: Любопытная RT-ошибка "pure virtual function is called"
От: Кодт Россия  
Дата: 17.11.09 10:17
Оценка: 6 (2)
Здравствуйте, <Аноним>, Вы писали:

А>Вопрос: как и почему вызов деструктора повлиял на экземпляр 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>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.