когда / почему я должен использовать виртуальный деструктор?
Следуйте указаниям Херб Саттерс :
Деструктор базового класса должен быть либо общедоступным и виртуальным, либо защищенным и не виртуальным
Может ли это быть классифицировано как неопределенное поведение (мы знаем, что ~ D () не будет вызываться наверняка)?
Это неопределенное поведение в соответствии со стандартом, которое обычно приводит к тому, что деструктор производного класса не вызывается и приводит к утечке памяти, но не имеет смысла спекулировать после результатов Неопределенного поведения, потому что стандарт ничего не гарантирует в этом отношении.
C ++ 03 Стандарт: 5.3.5 Удалить
5.3.5 / 1:
Оператор delete-expression уничтожает наиболее производный объект (1.8) или массив, созданный новым выражением.
удалить выражение:
:: opt delete cast-expression
:: opt delete [] cast-expression
5.3.5 / 3:
В первом альтернативном варианте (удаление объекта), если статический тип операнда отличается от его динамического типа, статический тип должен быть базовым классом динамического типа операнда, а статический тип должен иметь виртуальный деструктор или поведение не определено. Во втором варианте (удаление массива), если динамический тип удаляемого объекта отличается от его статического типа, поведение не определено.73)
Что если ~D()
пусто. Повлияет ли это на код?
Тем не менее, это неопределенное поведение в соответствии со стандартом. Деструктор производного класса, будучи пустым, может просто заставить вашу программу работать нормально, но это опять-таки определенный аспект реализации конкретной реализации, технически это все еще неопределенное поведение.
Обратите внимание, что здесь нет гарантии того, что не превращение деструктора производного класса в виртуальный просто не приведет к вызову деструктора производного класса, и это предположение неверно. В соответствии со Стандартом все ставки отменяются после того, как вы пересечете землю неопределенного поведения.
Обратите внимание, что он стандартно говорит о неопределенном поведении.
Стандарт C ++ 03: 1.3.12 неопределенное поведение [defns.undefined]
поведение, которое может возникнуть при использовании ошибочной программной конструкции или ошибочных данных, к которым настоящий международный стандарт не предъявляет никаких требований. Неопределенное поведение также может ожидаться, когда в этом международном стандарте опущено описание любого явного определения поведения. [ Примечание: допустимое неопределенное поведение варьируется от полного игнорирования ситуации с непредсказуемыми результатами до поведения во время
перевод или выполнение программы документированным образом, характерным для среды (с выдачей или без выдачи диагностического сообщения), до прекращения перевода или исполнения (с выдачей диагностического сообщения). Многие ошибочные программные конструкции не порождают неопределенное поведение; они должны быть диагностированы. ]
Если не вызывается только производный деструктор, это регулируется полужирным текстом в приведенной выше цитате, который явно оставлен открытым для каждой реализации.