3
#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.

STL programmer
  • 141
  • 2
  • 10
  • virtual tells compiler that take copy of methods and member variables from base not from middle2 – Prasad Mar 19 '13 at 11:37

3 Answers3

5

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.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

I know that virtual solves this problem, but how?

virtual keywords solves the problem by making only one top order base class subobject to be present in the inheritance hierarchy. Without it each parent class middle1 & middle2 have their own copy of the base class thus resulting in ambiguity.

Can we always write public virtual for safety, even we don't have multiple inheritance.

There is no reason to use virtual inheritance if you don't have multiple inheritance. Multiple inheritance is the purpose for concept of virtual inheritance to exist.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Virtual base classes implement an additional indirection level in order to solve the diamond problem (see this question).

If you always use virtual inheritance, you will always suffer the performance penalty resulting from that additional indirection level.

Therefore, I would suggest you only use virtual inheritance when you have to.

Community
  • 1
  • 1
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479