MyTetra Share
Делитесь знаниями!
Про нужность виртуального деструктора
Время создания: 12.02.2009 17:21
Текстовые метки: c++, виртуальный, деструктор, класс
Раздел: Компьютер - Программирование - Язык C++ (Си++)
Запись: xintrea/mytetra_syncro/master/base/0000000757/text.html на raw.github.com

В языке программирования C++ деструктор базового (полиморфного) класса должен объявляться виртуальным. Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.



Внимание!

Забегая вперед, надо отметить важную вещь: при описании виртуального деструктора нужно обязательно написать его реализацию, даже если она "пустая". Если забыть написать реализацию, то компиляция может пройти без ошибок и предупреждений, но ошибка возникнет в рантайме.



Обычным является использование виртуального деструктора в классах, имеющих виртуальные функции. Более того, gcc, например, выдаст вам предупреждение, если вы не сделаете виртуальным деструктор, объявив хотя бы одну виртуальную функцию. Это происходит из-за того, что если в классе есть хотя бы одна виртуальная функция, то в скомпилированном представлении класса появляется таблица виртуальных функций VTABLE, а сам класс начинает считаться виртуальным. Компилятор видит, что класс виртуальный, и рекомендует сделать деструктор виртуальным.


Часто можно встретить миф: «Виртуальный деструктор нужен лишь в том случае, когда на деструктор классов-потомков возлагаются какие-то нестандартные функции. Если деструктор потомка не отличается по функционалу от родителя, то делать его виртуальным нет особого смысла». Да, это может и будет работать «сейчас», но может сыграть злую шутку в будущем, да и в общем-то не очень верно.





Основная проблема в том, что если деструктор не виртуальный, то будет вызван деструктор того типа, какой заявлен в указателе. А ведь указатель запросто может иметь тип базового класса, хотя указывает на объект производного класса. Однако будет правильнее, что бы для объектов-потомков вызывались свои деструкторы. Просто стоит принять это как правило, иначе в будущем могут быть очень большие проблемы с отладкой непонятно почему текучих в плане памяти программ.


Пример определения виртуального деструктора:



class Record

{

public:

Record();

virtual ~Record();

...

};



Пример реализации виртуального деструктора (синтаксис реализации ничем не отличается от обычного деструктора):



Record::~Record()

{

...

}



Примечание: для лучшего понимания, как на самом деле вызываются виртуальные методы (включая деструктор), подготовлена следующая статья: Понимание наследования и механизма виртуальных методов в C++.


Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования