Алмазная проблема

Я решал проблему с бриллиантами и думал, что это сработает в различных сценариях. И это один из них, над которым я работал.

#include <iostream> 
using namespace std;
class MainBase{

    public:
    int mainbase;
    MainBase(int i):mainbase(i){}
    void geta()
    {
        cout<<"mainbase"<<mainbase<<endl;
    }
};
class Derived1: public MainBase{

    public:
    int derived1;
    int mainbase;
    Derived1(int i):MainBase(i),derived1(i) {mainbase = 1;}
    public:
    void getderived1()
    {
        cout<<"derived1"<<derived1<<endl;
    }

};
class Derived2: public MainBase{

    public:
    int derived2;
    int mainbase;
    Derived2(int i):MainBase(i),derived2(i){mainbase = 2;}
    public:
    void getderived2()
    {
        cout<<"derived2"<<derived2<<endl;
    }
};
class Diamond: public Derived1, public Derived2{

    public:
    int diamond;
    int mainbase;
    Diamond(int i,int j, int x):Derived1(j),Derived2(x),diamond(i){mainbase=3;}
    public:
    void getdiamond()
    {
        cout<<"diamond"<<diamond<<endl;
    }
};
int main()
{
    Diamond d(4,5,6);
//    cout<< d.MainBase::mainbase;
    cout<<"tested"<<endl;
    cout<<d.mainbase;
    cout<<d.Derived2::mainbase<<endl;
    cout<<d.Derived1::mainbase<<endl;
    /*cout<<d.Derived2::MainBase::mainbase<<endl;
    cout<<d.Derived1::MainBase::mainbase<<endl;*/
}

Теперь мне интересно, как мне получить доступ к основной переменной класса MainBase? Любые входы.


person Lakshmi    schedule 12.08.2009    source источник
comment
Исправьте код, пожалуйста. Выберите все это и нажмите 010101.   -  person jkeys    schedule 12.08.2009
comment
Действительно, смотреть на это кошмар. :(   -  person Michael Foukarakis    schedule 12.08.2009
comment
Проблема алмаза: в объектно-ориентированных языках программирования с множественным наследованием и организацией знаний проблема алмаза — это двусмысленность, которая возникает, когда два класса B и C наследуют от A, а класс D наследует оба от B и C. Если метод в D вызывает метод, определенный в A (и не переопределяет метод), а B и C переопределяют этот метод по-разному, то от какого класса он наследуется: B или C? источник: en.wikipedia.org/wiki/Diamond_problem   -  person Adriaan    schedule 12.08.2009


Ответы (3)


Вы делаете то, что вы сделали там:

cout<<d.Derived2::MainBase::mainbase<<endl;
cout<<d.Derived1::MainBase::mainbase<<endl;

Но это может не сделать то, чего вы пытаетесь достичь. Возможно, вам следует использовать наследование virtual? То, что у вас есть, означает, что в вашем объекте будет две копии членов MainBase, по одной для каждой дорожки наследования.

(из MSDN).

Когда базовый класс указан как виртуальная база, он может выступать в качестве косвенной базы более одного раза без дублирования своих элементов данных. Единственная копия его элементов данных совместно используется всеми базовыми классами, использующими ее в качестве виртуальной базы.

Возможно, вам больше подойдет что-то вроде этого:

class Derived1: virtual public MainBase{
person 1800 INFORMATION    schedule 12.08.2009

Ваш код не будет компилироваться, существует двусмысленность при обращении к Mainbase как к базе экземпляра Diamond. Вам нужно использовать virtual в производных классах (Derived1, Derived2), чтобы разрешить эту неоднозначность, разрешив им совместно использовать один экземпляр базового класса, например:

class Derived1: virtual public Mainbase {
/* do your thing here*/
};
person Michael Foukarakis    schedule 12.08.2009

Вы должны иметь доступ к нему из класса Diamond следующим образом:

Diamond::foo() {
    Mainbase::mainbase = 0;
}

Предполагая, что ваш код изначально правильно компилируется. См. Майкл Фукаракис ответ для получения дополнительной информации о компиляции. Также см. отличную статью от DDJ: "Множественное наследование считается полезным" о том, как это сделать. правильно.

person Nathan Fellman    schedule 12.08.2009