Ключевое слово virtual не может быть использовано вместе с конструкторами, однако деструкторы могут и часто должны быть виртуальными (см. п. п. 12.4/7 в [1]).
Если мы работаем с объектом производного класса через указатель базового класса, то при уничтожении объекта будет вызван деструктор только базового класса. А нам нужно, чтобы сначала был вызван деструктор производного класса, а в нем уже — деструктор базового класса. Такие ошибки очень трудно находить: до поры, до времени программа работает нормально. Но в один «прекрасный» моме...
Здесь мы имеем все ту же проблему, для решения которой и были придуманы виртуальные функции. Естественно, «отец-основатель» прекрасно понимал всю серьезность проблемы. Поэтому деструкторы тоже могут быть объявлены виртуальными, и для таких деструкторов выполняется динамическое связывание. Простой пример демонстрирует работу виртуальных деструкторов (листинг 9.7).
Листинг 9.7. Виртуальные деструкторы
class Base { public:
~Base() // деструктор не виртуальный
{ cout << "Base::Not virtual destructor!"<< endl: }
class Derived: public Base // наследник
{ public:
~Derived() // деструктор не виртуальный
{ cout << "Derived::Not virtual destructor!"<< endl; }
class VBase { public:
virtual ~VBase() // деструктор виртуальный
{ cout << "Base::virtual destructor!"<< endl; }
class VDerived: public VBase
{ public: // деструктор виртуальный
~VDerived() // virtual можно не писать
{ cout << "Derived::virtual destructor!"<< endl; }
int main()
{ Base *bp = new DerivedO; // подстановка - повышающее приведение типа
delete bp; // вызывается только базовый деструктор
VBase *vbp = new VDerivedO; // подстановка
delete vbp; // вызывается производный, а потом базовый
return 0;
}
При выполнении оператора delete bp будет вызван деструктор только базового класса — налицо утечка памяти, так как был создан и не уничтожен объект производного класса. При выполнении оператора delete vbp все работает правильно, так как вызывается сначала деструктор производного класса, а потом базового (происходит динамическое связывание виртуального деструктора). |