Деструктор
- Деструктор полиморфных классов должен быть виртуальным. Это же правило касается описания интерфейсов (как правило, чисто абстрактных классов). Это необходимо для корректного удаления экземпляра класса через указатель на его базовый класс.
- Неполиморфные классы либо должны объявляться как final, либо деструктор в таких классах должен располагаться в protected области видимости (чтобы его мог вызвать деструктор дочернего класса), либо класс не должен иметь состояний (stateless) и к нему применяется оптимизация EBCO.
Пример:
class X {
public:
~X(); // Плохо! деструктор не виртуальный
// публичные функции
private:
// члены класса
}
class Y : public X {
public:
~Y();
// публичные функции
private:
// члены класса
}
int main() {
std::unique_ptr<X> x = std::make_unique<Y>();
return 0;
}
Если вы уверены, что от вашего класса наследоваться не должны, указывайте явно final:
class X final {
public:
~X(); // OK!
// публичные функции
private:
// члены класса
}
int main() {
auto x = std::make_unique<X>();
return 0;
}
Если вы хотите запретить удалять класс через указатель на базовый, поместите деструктор в protected область в базовом классе: