If I remember everything correctly, when diamond-shaped inheritance, the Multi class will have two copies of Base. But if virtual inheritance is made, the copy will be one. It is for this reason that two times displayed, then one.
UPD: A strange, synthetic example, but maybe someone will save time.
#include <iostream> class Base { public: int k; Base() { std::cout<<"Create!"<<std::endl; k = 0; } ~Base() { std::cout << "Delete " << k << std::endl; } }; class Sub1 : public virtual Base {}; class Sub2 : public Base {}; class Sub3 : public virtual Base {}; class Sub4 : public Base {}; class Multi : public Sub1, public Sub2, public Sub3, public Sub4 { public: Multi() { if (Sub1::k == 0) Sub1::k = 1; else std::cout << " try init 1, but was init by " << Sub1::k << std::endl; if (Sub2::k == 0) Sub2::k = 2; else std::cout << " try init 2, but was init by " << Sub2::k << std::endl; if (Sub3::k == 0) Sub3::k = 3; else std::cout << " try init 3, but was init by " << Sub3::k << std::endl; if (Sub4::k == 0) Sub4::k = 4; else std::cout << " try init 4, but was init by " << Sub4::k << std::endl; } }; int main() { Multi m; return 0; }
Conclusion:
Create! Create! Create! try init 3, but was init by 1 Delete 4 Delete 2 Delete 1
To understand, you need to know that Sub1::k
is a special form to refer to the correct branch in rhomboid inheritance (with the word I specifically got excited, of course - it works in other inheritances :)). As you can see, there are no zeros in the destructor output, so exactly all copies of Base
initialized. But as you can see, one copy (number 3) was not reinitialized. Destructors are usually called in the reverse order.