0

I have this part of code

#include <iostream>
using namespace std;
class A {
public:
int i;
    A(){i = 0; }
    virtual void f() { cout << i; }
};
class B1 : virtual public A {
public:
    B1() { f(); }
    void f() { cout << i+10; }
};
class B2 : virtual public  A {
public:
    B2() { f(); }
    void f() { cout << i+1; }
};
class C : public B1, public B2 {
public:
    C() {}
};
void main(){
    C c;
    //c.A::f();
}

First, I understand the main idea behind using virtual inheritance (diamond) in order to create only one A object in memory.

In this example, I get compilation error in C class:

override of virtual function "A::f" is ambiguous

If I remove the virtual inheritance. The code compiles, there is no error in class C as before.

If I remove the comment from the last code line it still compiles. I understand that in this case the f() function that will be executed is the one from the first class that C inherits from.

Now, if I replace c.A::f() with c.f() I get a compilation error at this specific line.

Can someone please explain this behaviour and the differences between these cases?

Ohad C.
  • 76
  • 5

2 Answers2

3

The problem is with C not with your expression call. As f is virtual and redefined twice in B1 and B2 then the C class is malformed because a call to fwould be ambiguous (which override to choose?). Add an override of f in Cand everything will be ok.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
-1

Within the class C you must choose which variant of f to usr. That is, using B1::f; or using B2::f.

Paul Stelian
  • 1,381
  • 9
  • 27
  • I know how to make it work, but I am trying to understand the concept and reasons for this behaviour. – Ohad C. Jul 02 '16 at 09:19
  • The reason is it sees two conflicting definitions in the two base classes and it doesn't know which. My solution says which one you want it to use. – Paul Stelian Jul 02 '16 at 09:21