Деструктор базового класса должен быть только virtual
, если вы можете попытаться освободить объект производного типа через указатель базового типа.Следовательно, если вы наследуете только от базового класса в частном порядке вместо публично , как в случае с Uncopyable
, вам не нужно беспокоиться о добавлении virtual
деструктор, потому что при использовании частного наследования вы не можете получить указатель на производный объект и сохранить его в указателе на базовый тип.
Другой пример может быть, если вы будете использовать класс mixin, такой какэто тот, который заставляет класс отслеживать количество распределений объектов, от которых наследуется миксин для получения поведения, но не для полиморфной обработки:
template <typename T> class Counter {
public:
Counter() { ++numInstances; }
Counter(const Counter&) { ++numInstances );
~Counter() { --numInstances; }
static unsigned getNumInstances() { return numInstances; }
private:
static unsigned numInstances;
}
template <typename T> unsigned Counter<T>::numInstances = 0;
В более общем случае при использовании статического полиморфизманужны виртуальные деструкторы, потому что вы никогда не обрабатываете классы полиморфно, используя указатели на базовый тип.Вы используете только указатель на производный тип.
Возможно, есть еще несколько случаев, которые я здесь не охватил, но эти два (частное наследование, классы смешивания и статический полиморфизм) покрывают большую часть пространства, гдевиртуальные деструкторы не требуются.