Здравствуйте Аноним, Вы писали:
А>Здравствуйте PaNov, Вы писали:
PN>>Кстати, недавно наступал на аналогичные грабли с точностью до наоборот... PN>>Я в деструкторе базового класса вызывал виртуальную функцию, в надежде что она вызовет функцию, переопределенную в дочернем классе. PN>>К тому времени отрабатывали деструкторы всех дочерних классов и по-всей видимости функции удалялись из таблицы виртуальных функций.
А>Ошибка у вас в рассуждениях, однако.
А>Пример: А>class A А>{ А>public: А> ~A() { TRACE("A::~A()\n"); } А>}; А>class B : public A А>{ А>public: А> ~B() { TRACE("B::~B()\n"); } А>};
А>Что по-вашему, будет в Output окошке? Правилно, вот это: А>B::~B() А>A::~A()
А>Т.е. ваш собственный код (который вместо "TRACE("B::~B()\n");") вызывается до деструктора класса А. И ТВФ все еще валидна в этот момент, и правильная виртуальная функция будет вызвана.
Читай внимательнее. "Дочерним классом" назывется класс-потомок, а не класс-предок. В данном случае дочерним классом является класс 'B'. Его деструктор вызывается первым. К моменту вызова деструкора класса 'A' деструкор дочернего класса 'B' уже закончил свое черное дело, как и сказал предыдущий оратор.
"Удаление функций из таблицы" — это, конечно, ерунда. Но порядок отработки деструкторов был назван совершенно правильно.