Виникло питання щодо віртуального деструктора.
Наскільки я зрозумів - віртуальний деструктор потрібен, щоб в успадковувати класі, який у нас є (від базового) можна було викликати (прямо звідти) деструктор базового, а тому простий деструктор успадкованих клас не розуміє, то потрібно створювати віртуальний.
І все це щоб не було ніякого витоку пам'яті.
Так я зрозумів суть?
Не, трохи не так. Деструкція базового класу з деструктора похідного викликати не треба (та й не можна), він сам зголоситься автоматично. Проблема в іншому: деструктор похідного класу може бути не викликаний!
Уявіть собі таку ситуацію:
Що трапиться, якщо в списку буде один Spy. А ось що: при знищенні об'єкта типу Spy за вказівником типу Person * зголоситься невіртуальний деструктор
Person. Значить, пам'ять під масив gadgets не буде звільнено. Ось вам і витік пам'яті.
Насправді, крім витоку пам'яті може статися будь-яка інша неприємність, адже деструктор, на який ви розраховували, що не зголоситься! Наприклад, може не закритися файл, і при наступній спробі його відкрити програма вилетить. Хіба ви не проститься м'ютекс, і при спробі його отримати програма зависне. Ну і ще купа всяких катастроф може статися.
Гірше того, за стандартом відсутність віртуального деструктора в даному випадку є undefined behaviour, тобто, програма має право зробити що завгодно: відформатувати вінчестер, зізнатися в любові до вашої Хімічка через «Вконтакте» або підлити валер'янки в миску з Віскас.
Так, а в C деструкторов немає зовсім.
Додам до дуже хорошому поясненню користувача VladD наступний код, який дуже часто можна зустріти всюди:
Результатом виконання буде:
Зверніть увагу на порядок викликів конструкторів і деструкторів. Деструктори викликаються в зворотному порядку щодо викликів конструкторів. А тепер заберіть ключове слово virtual з
Derive (). як наслідок деструктор класу Derive НЕ буде викликаний:
Якщо від Вашого базового класу планується далі успадковуватися інші класний деструктор повинен бути віртуальний. Рекомендую почитати Скота Мейерса, у нього відмінні книги по C ++.