2015-04-21 3 views
1

Я слышал, что использование виртуального ключевого слова решает проблему с алмазом.Наследование диалогов в множественном наследовании с использованием ключевого слова Virtual

Однако, когда я сделал это:

#include <iostream> 

using namespace std; 

class A { 
public: 
    A(int x = 100) { 
     num = x; 
    } 
protected: 
    int num; 
}; 

class B1 : virtual public A{ 
public: 
    B1(int x = 50) : A(2*x) { 
    } 
}; 
class B2 : virtual public A{ 
public: 
    B2(int x = 50) : A(2*x) { 
    } 
}; 
class C : public B1, public B2 { 
public: 
    C(int x = 75) : B1(2*x), B2(2*x) {}; 
    int getData(){ return num; } 
}; 

int main() { 
    C c(10); 

    cout << c.getData(); 
    cin.get(); 
    return 0; 
} 

Он отображает вывод как 100 вместо того, что я ожидал, т.е. 40. Почему?

+2

Виртуальный базовый класс инициализируется в * наиболее производном классе * (тип фактического объекта, который вы создаете). Поскольку для 'A' в' C' нет инициализатора, аргумент конструктора 'A' ​​по умолчанию равен 100. – dyp

+0

Или любой базовый класс? –

+0

Простите, я не понимаю, о чем вы говорите. – dyp

ответ

2

При использовании виртуального наследования у вас гарантированно есть один экземпляр общего базового класса (cite); поэтому B1 и B2 не могут иметь свой экземпляр A, но они будут совместно использовать один экземпляр с C. Например, если вы определили конструктор C «s следующим образом:

C(int x = 75) : B1(2*x), B2(2*x), A(x) {}; 

вы увидите код выхода 10. Ключ в том, что @dyp прокомментировал:

общий базовый класс инициализируется в наиболее производном классе

(Конечно, в приведенном выше примере это не имеет никакого смысла, чтобы все B1, B2 и A в списке инициализаторов, как имеющих A).

+0

Whoooooooooooooooo !!!!!!!!!!!!!!!!!!! Да!!! Благодарю. Я понял эту концепцию! –