2016-07-02 5 views
0

У меня есть эта часть кодаВиртуального наследования неоднозначной функция

#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(); 
} 

Первой, я понимаю, основная идею использования виртуального наследования (ромб) для того, чтобы создать только один A объекта в памяти.

В этом примере, я получаю ошибку компиляции в классе C:

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

Если удалить virtual наследство. Код компилируется, нет ошибки в классе C, как и раньше.

Если я удалю комментарий из последней строки кода, он все еще компилируется. Я понимаю, что в этом случае функция f(), которая будет выполнена, является первой из первого класса, которую наследует C.

Теперь, если я меняю c.A::f() на c.f() Я получаю ошибку компиляции на этой конкретной строке.

Может кто-нибудь объяснить это поведение и различия между этими случаями?

+0

Кто сказал, что не по теме ??? Это просто дубликат. –

ответ

3

Проблема с C не с вызовом выражения. Поскольку f является виртуальным и переопределяется дважды в B1 и B2, тогда класс C неверен, потому что вызов f будет неоднозначным (который переопределяет выбор?). Добавьте переопределение f в C, и все будет в порядке.

-1

В классе C вы должны выбрать вариант f для usr. То есть, using B1::f; или using B2::f.

+0

Я знаю, как заставить его работать, но я пытаюсь понять концепцию и причины такого поведения. –

+0

Причина в том, что он видит два противоречивых определения в двух базовых классах и не знает, что. Мое решение говорит, какой из них вы хотите использовать. –

Смежные вопросы