Виртуальные деструкторы необходимы, когда объект (потенциально) разрушается из указателя базового класса.
Рассмотрим программу без динамической памяти, которая часто встречается во встроенных системах. Здесь, используя new
или же delete
вызывает ошибку компоновщика, потому что необходимые базовые распределители не реализованы. Таким образом, разработчики используют только статически размещенные объекты (в разделе bss / data) или автоматически размещаемые объекты (обычно в стеке).
В такой системе, есть ли ситуация, когда виртуальный деструктор действительно нужен? (Допустим, никто не скучает и вызывает деструктор вручную по некоторому указателю.)
Мне кажется, что статическое и автоматическое распределение всегда вызывает правильный деструктор в любом случае. Я что-то пропустил? Есть ли угловые случаи? Как насчет пулов статических объектов в сочетании с unique_ptr и пользовательским средством удаления?
Допустим, никто не скучает и вызывает деструктор вручную по некоторому указателю.
Я думаю, что вы упустили эту возможность слишком быстро. Встроенные системы / системы с ограниченным объемом памяти, где динамическое размещение запрещено, все еще могут создавать объекты с динамическим хранением продолжительность. Заметим:
alignas(T) char memory[sizeof(T)];
T *p = new(memory) T; //Does not call global `new` allocator.
/*do stuff with `p`*/
p->~T();
Нет причин запрещать это. Действительно, некоторые реализации стирания типов полагаются на это при оптимизации небольших объектов. std::any
реализации для небольших объектов могут создавать производный класс, полностью используя память в std::any
сам объект Но он все еще должен вызывать деструктор типа, обычно через указатель базового класса. Есть реализации any
тот не Конечно, используйте наследование, но в целом я хочу сказать, что было бы странно прямо запретить вызов деструктора вручную.
Других решений пока нет …