为什么虚拟析构函数需要删除运算符

fel*_*ght 13 c++ delete-operator virtual-destructor

在使用g ++的独立上下文(没有标准库,例如在操作系统开发中)中,会出现以下现象:

class Base {
public:
   virtual ~Base() {}
};

class Derived : public Base {
public:
    ~Derived() {}
};

int main() {
    Derived d;
}
Run Code Online (Sandbox Code Playgroud)

链接时,它表示如下: undefined reference to operator delete(void*)

这显然意味着即使动态内存分配为零,g ++也会生成删除运算符的调用.如果析构函数不是虚拟的,则不会发生这种情况.

我怀疑这与课堂生成的vtable有关,但我不完全确定.为什么会这样?

如果由于缺少动态内存分配例程而不能声明删除操作符,是否有解决方法?

EDIT1:

为了成功地重现g ++ 5.1中的问题,我使用了:

g ++ -ffreestanding -nostdlib foo.cpp

Ste*_*oft 13

因为删除了析构函数.这是delete obj在使用虚拟析构函数调用对象时实际调用的函数.它调用完整的对象析构函数(它链接基础对象析构函数 - 您实际定义的那些)然后调用operator delete.这样,在所有使用的地方delete obj,只需要发出一个调用,并且还用于使用ISO C++要求operator delete返回的相同指针进行调用operator new(尽管这也可以通过更高成本完成dynamic_cast) .

它是GCC使用的Itanium ABI的一部分.

我不认为你可以禁用它.

  • 我认为还有一个额外的原因你没有提到(显式):可以在派生类中重载`operator delete`; 标准[class.free] p4要求动态(有效)调度`delete`*如果`delete`操作数**的静态类型有虚拟dtor***.也就是说,如果你定义了一个虚拟析构函数,你将有效地获得一个虚拟的`operator delete`.[实例](http://coliru.stacked-crooked.com/a/0cb0d7aeced8caa0) (3认同)
  • @Felipe否,删除析构函数只能用`delete`调用 (2认同)