紀冠瑋
紀冠瑋

Reputation: 31

Destructor in virtual inheritance

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?

Upvotes: 2

Views: 2152

Answers (2)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145269

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.

Upvotes: 4

Some programmer dude
Some programmer dude

Reputation: 409176

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.

Upvotes: 5

Related Questions