I have Y-shaped class hierarchy: class C inherits from A and B, and class D inherits from C. A and B have virtual destructors and C's destructor is not virtual. I know that if there is no double inheritance (say no B) ~C() will be virtual. My question is does double inheritance affects it?
class A { virtual ~A(); ...};
class B { virtual ~B(); ...};
class C : public A, public B { ~C(); ...};
class D : public C { virtual ~D(); ... };
I have to delete instances of class D through a pointer to C.
C* c = new D;
delete c;
I suspect that there are some corner cases where ~B() is not executed - is it possible? Can it depend upon level of optimizations? Should definition of to D present in .cc file where 'delete c' is called?
All destructors except ~B() are nops, class C is empty class: no data members, no functions, just a trivial constructor and an empty destructor. I wrote several test programs in all cases ~B() was executed, but I am sure I did not try all the possible combinations.
C
destructor is implicitly virtual since at least one of its base destructor is virtual.
Thus because C
destructor is virtual and you delete through a pointer to C
, D
destructor would be called.
If neither A
or B
destructor would be virtual, then it would be undefined behavior to delete a D
object but this is not the case here.
If a class C
derive from class(es), then it knows how to destroy its base classes. Thus B
destructor would always be called (assuming that you delete either the final object or from a level where the destructor is virtual either explicitly or implicitly.
In practice, even in the undefined case (only D
destructor is virtual and object is deleted through C
pointer), B
destructor would probably have been called but D
part would not have been properly destroyed. But since, it is undefined, you cannot rely on that.