Нужны ли виртуальные деструкторы в мире без динамической памяти?
Виртуальные деструкторы необходимы, когда объект (потенциально) разрушается из указателя базового класса.
Рассмотрим программу без динамической памяти, которая часто встречается во встроенных системах. Здесь, используя new
или же delete
вызывает ошибку компоновщика, потому что необходимые базовые распределители не реализованы. Таким образом, разработчики используют только статически размещенные объекты (в разделе bss / data) или автоматически размещаемые объекты (обычно в стеке).
В такой системе, есть ли ситуация, когда виртуальный деструктор действительно нужен? (Допустим, никто не скучает и вызывает деструктор вручную по некоторому указателю.)
Мне кажется, что статическое и автоматическое распределение всегда вызывает правильный деструктор в любом случае. Я что-то пропустил? Есть ли угловые случаи? Как насчет пулов статических объектов в сочетании с unique_ptr и пользовательским средством удаления?
1 ответ
Допустим, никто не скучает и вызывает деструктор вручную по некоторому указателю.
Я думаю, что вы упустили эту возможность слишком быстро. Встраиваемые системы / системы с ограниченным объемом памяти, в которых динамическое выделение запрещено, все еще могут создавать объекты с динамической продолжительностью хранения Заметим:
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
конечно, это не использует наследование, но в целом я хочу сказать, что было бы странно прямо запретить вызов деструктора вручную.