Почему оператор удаления требуется для виртуальных деструкторов
В автономном контексте (без стандартных библиотек, например, при разработке операционной системы) с использованием g++ возникает следующее явление:
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
~Derived() {}
};
int main() {
Derived d;
}
При связывании это говорит примерно следующее: undefined reference to operator delete(void*)
Это явно означает, что g++ генерирует вызовы для удаления оператора, даже если имеется нулевое распределение динамической памяти. Этого не происходит, если деструктор не является виртуальным.
Я подозреваю, что это связано с созданной vtable для класса, но я не совсем уверен. Почему это происходит?
Если я не могу объявить оператор удаления из-за отсутствия динамических программ распределения памяти, существует ли работа?
EDIT1:
Чтобы успешно воспроизвести проблему в g++ 5.1, я использовал:
g++ -ffreestanding -nostdlib foo.cpp
Ответы
Ответ 1
Из-за удаления деструкторов. Это функции, которые на самом деле вызываются при вызове delete obj
объекта с виртуальными деструкторами. Он вызывает полный деструктор объекта (который связывает базовые объекты-деструкторы - те, которые вы фактически определяете), а затем вызывает operator delete
. Это значит, что во всех местах, где используется delete obj
, требуется только один вызов, а также используется для вызова operator delete
с тем же указателем, который был возвращен из operator new
в соответствии с требованиями ISO С++ (хотя это может быть сделано более дорогостоящим с помощью dynamic_cast
).
Это часть Itanium ABI, которую использует GCC.
Я не думаю, что вы можете отключить это.