Destructor in virtual inheritance

谁都会走 提交于 2020-01-20 08:41:27

问题


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;
}

This leads to crash, but I modify as below:

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{
};

Then, it passes, but the default destructor should be the virtual dummy function, isn't it?


回答1:


From the C++11 specification (ISO/IEC 14882:2011(E)), section 12.4 Destructors [class.dtor]:

Sub-section 4:

If a class has no user-declared destructor, a destructor is implicitly declared as defaulted (8.4). An implicitly-declared destructor is an inline public member of its class.

Sub-section 6:

A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to destroy an object of its class type (3.7) or when it is explicitly defaulted after its first declaration.

And finally sub-section 9:

A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.

Emphasis mine in the last quote.

The compiler will generate a virtual destructor only if the base class have a virtual destructor. If the base class doesn't have a virtual destructor, like Base in your first example, then the child-classes will not have virtual destructors. And if a class doesn't have a base-class the compiler-generated destructor will not be virtual.




回答2:


This has nothing to do with virtual inheritance.

Deleting via a pointer to type T other than the originally allocated type D is Undefined Behavior unless the type T is a base class of D and has a virtual destructor.

C++14 (as in N3936 draft) §5.3.5/3

… if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

The virtual destructor is used to identify the type D, in particular its size and its destructor, and possibly its custom deallocation function (your code doesn't have that).


Re

the default destructor should be the virtual dummy function, isn't it?

No, it isn't.

Because one guiding principle of the design of C++ is that you don't pay for what you don't use, and another guiding principle is to leave the programmer in control, with the ability to express whatever's needed (e.g. for purposes of binary layout in memory).

You get a default virtual destructor only if the base class has a virtual destructor.



来源:https://stackoverflow.com/questions/36760797/destructor-in-virtual-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!