虚拟继承中的析构函数

紀冠瑋*_*紀冠瑋 2 c++ destructor virtual-inheritance delete-operator virtual-destructor

class Base{};
class D1:virtual public Base{};
class D2:virtual public Base{};
class DD:public D1,public D2{};

int main(){
    Base *pBase=new DD;
    delete pBase;
}
Run Code Online (Sandbox Code Playgroud)

这会导致崩溃,但我修改如下:

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

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

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

class DD:public D1,public D2{
};
Run Code Online (Sandbox Code Playgroud)

然后,它就通过了,但是默认的析构函数应该是虚拟虚拟函数,不是吗?

Som*_*ude 5

来自 C++11 规范 (ISO/IEC 14882:2011(E)),第 12.4 节析构函数 [class.dtor]:

第 4 小节:

如果类没有用户声明的析构函数,则析构函数将隐式声明为默认析构函数 (8.4)。隐式声明的析构函数是其类的内联公共成员。

第 6 小节:

当析构函数被默认且未定义为删除时,当它被 odr 使用(3.2)来销毁其类类型(3.7)的对象时,或者当它在第一次声明后被显式默认时,它被隐式定义。

最后是第 9 小节:

析构函数可以声明为虚函数(10.3)或纯虚函数(10.4);如果程序中创建了该类或任何派生类的任何对象,则应定义析构函数。如果一个类有一个带有虚拟析构函数的基类,那么它的析构函数(无论是用户声明的还是隐式声明的)都是虚拟的。

最后引用中强调我的观点。

当基类具有虚拟析构函数时,编译器才会生成虚拟析构函数。如果基类没有虚拟析构函数(如Base第一个示例中所示),则子类将不会有虚拟析构函数。如果一个类没有基类,则编译器生成的析构函数将不是虚拟的。