Здравствуйте, cppNewbie, Вы писали:

N>Если инициализировать указатель родительского класса адресом объекта дочернего класса и объявить в родительском классе деструктор виртуальным, то при "разрушении" дочернего объекта через этот указатель сначала выполнится деструктор дочернего класса, а потом деструктор родителя. То, что выполняется деструктор дочернего объекта — мне понятно, потому что мы объявили деструктор родителя виртуальным. Но почему выполняется деструктор родительского класса? Есть ли этому логичное объяснение или это нужно принять как данность? Ведь при выполнении метода через указатель или ссылку родительского типа, если одноименный метод в предке объявлен виртуальным, исполняется только один метод, тот, который принадлежит дочернему объекту.


Чем деструктор отличается от любой другой функции...
Деструктор сперва выполняет код, написанный в { ... }, затем деструкторы всех членов-данных, затем деструкторы всех обычных баз, затем деструкторы всех виртуальных баз.
Вне зависимости от того, виртуальный деструктор или не виртуальный.

Зачем нужна виртуальность?
class Base { ... };

class Child : public Base { ... };

main()
{
  Base* ptr = new Child;

  ...

  delete ptr; // ***
}

В точке *** у объекта *ptr вызывается деструктор класса Base (поскольку про то, Child там или не Child — компилятор не знает).
Если деструктор невиртуальный, то вызовется только деструктор базы — значит, всё, что должен выполнить деструктор Child'а, не произойдёт.
А если виртуальный — то из VMT возьмут адрес актуального деструктора.
Автор: Кодт    Оценить