Search code examples
c++virtualmultiple-inheritance

What is difference between class A:public virtual B and class A:public B


#include<iostream>
using namespace std;

class base
{
    public:
      virtual void f(){}
};

class middle1:public base
{};

class middle2:public base
{};

class derive:public middle1,public middle2
{};



int main()
{
    derive* pd=new derive();
    pd->f();
    return 0;
}

I know that virtual solves this problem, but how? Can we always write public virtual for safety, even we don't have multiple inheritance.


Solution

  • Each instance of derive has a middle1 base class sub-object and a middle2 base class sub-object.

    If the inheritance is non-virtual, then the middle1 base class sub-object has a base base class subobject, and the middle2 base class sub-object also has a base base class sub-object. Hence, each instance of derive has two base sub-objects, and the call pd->f() is ambiguous -- which of the base objects do you want to call f() on?

    Making the inheritance virtual means that middle1 and middle2 will share a single base sub-object of derive. This removes the ambiguity -- there is only one base object that f() could be called on.

    Can we always write public virtual for safety

    Not necessarily. There may be inheritance hierarchies in which you don't want middle1 and middle2 to share a public base sub-object. You could probably argue that in such cases, you shouldn't be writing a class derive that inherits from both, but if you do end up with that situation then the workaround would be to do either:

    static_cast<middle1*>(pd)->f();
    pd->middle1::f();
    

    to specify that you want to call f on the middle1 base class sub-object, or

    static_cast<middle2*>(pd)->f();
    pd->middle2::f();
    

    to specify middle2.