Почему (C++) не является виртуальными деструкторами, осуществленными для базового класса

Деструкторы не являются виртуальными по умолчанию для не причинения вреда, когда его не нужное, которое прекрасно.

Но в случае сценария производного класса базового класса, там какой-либо вариант использования для того, чтобы не иметь виртуальный деструктор? Если не мог он быть возможным (делает это имеет смысл) для компилятора, чтобы жаловаться, происходит ли класс из базового класса, который имеет общественность не виртуальный деструктор (или никакой деструктор) определенный. И не просто предупреждают об этом.

12
задан Michael0x2a 8 December 2013 в 19:02
поделиться

4 ответа

Проблема с вашей идеей заключается в том, что вполне возможно, что кто-то использует деструктор не виртуального базового класса в качестве оптимизации (если вы никогда не собираетесь уничтожать с помощью указателя базового класса, то отсутствующий виртуальный не повредит вам, и по-прежнему избегает записи vtable).

Поскольку его МОЖНО использовать, это разрешено. Я бы подумал, что необязательное предупреждение компилятора может быть хорошей идеей, но не что-то в спецификации языка.

12
ответ дан 2 December 2019 в 05:39
поделиться

Виртуальный деструктор нужен только в том случае, если вы выполняете полиморфное уничтожение объекта через delete. Это, в свою очередь, сразу же подразумевает динамически выделяемые (new-ed) объекты.

Если вы не выделяете объекты динамически, вам не нужен виртуальный деструктор. Это сразу же открывает неограниченный источник случаев использования, когда виртуальный деструктор в базовом классе не нужен.

Если вы выделяете объекты динамически, но никогда не уничтожаете их полиморфно, вам не нужен виртуальный деструктор. Это добавляет еще один набор случаев использования, когда виртуальный деструктор в базовом классе не нужен.

5
ответ дан 2 December 2019 в 05:39
поделиться

Потому что совершенно оправданно иметь невиртуальный деструктор. Если, например, подклассы предназначены только для выделения стека, то виртуальный деструктор не нужен. Зачем требовать от клиентов всего механизма vtbl, если класс должен быть только декоратором?

Также не имеет смысла иметь виртуальный деструктор, если класс предназначен для частного наследования (implemented-in-terms-of).

Все это говорит о том, что деструктор обычно должен быть публичным и виртуальным или защищенным, если только класс не предназначен для того, чтобы быть базовым классом.

8
ответ дан 2 December 2019 в 05:39
поделиться

Есть разные проблемы с тем, что вы предлагаете, первая из которых уже рассматривается в других ответах: вам нужны только виртуальные деструкторы, если вы собираетесь удалить через указатель на базу (общая рекомендация - предоставить либо общедоступный виртуальный деструктор или защищенный не виртуальный деструктор, поскольку это препятствует удалению через базовый класс).

Есть еще одна проблема: когда компилятор видит определение класса, он не может знать, будет ли он производным или нет. Подумайте, реализуете ли вы базовый класс в единице перевода. Позже вы выйдете из класса. Если этот вывод будет подразумевать создание виртуального конструктора, преобразование базового класса придется перекомпилировать, иначе ODR (одно правило определения) будет нарушено в вашей программе.

Если вы добавите в смесь другие единицы перевода, все станет еще хуже. Всякий раз, когда вы включаете файл заголовка из единицы перевода, вы также будете вынуждены вручную включить хотя бы один заголовок, в котором определен производный объект из этого класса (увеличивая связь), иначе, опять же, компилятор сгенерировать другое определение для этого единственного класса в этой единице трансляции (по сравнению с единицей трансляции, в которой определен производный класс), снова нарушив ODR.

Проблема в том, что компилятор имеет лишь частичное представление о вашем проекте и не может сделать вывод о том, что вам нужно / что вы хотите, из того, что он видит.

2
ответ дан 2 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: