Diamond problem

2019-08-04 23:48发布

问题:

I was going through the diamond problem and thought will work on various scenarios. And this is one among them which I was working on.

#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;*/
}

I am now wondering how to I access MainBase class mainbase variable? Any inputs.

回答1:

You do what you have done there:

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

But, it might not do what you are trying to achieve. Possibly, you should be using virtual inheritance? What you have means there will be two copies of the MainBase members in your object, one for each inheritance track.

(From MSDN).

When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members. A single copy of its data members is shared by all the base classes that use it as a virtual base.

Probably something like this will suit you better:

class Derived1: virtual public MainBase{


回答2:

Your code won't compile, there is an ambiguity when referring to Mainbase as a base of a Diamond instance. You need to use virtual in the derived classes (Derived1, Derived2) to resolve this ambiguity by allowing them to share a single instance of base class, like this:

class Derived1: virtual public Mainbase {
/* do your thing here*/
};


回答3:

You should be able to access it like this from the Diamond class:

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

Assuming that your code compiles properly in the first place. See Michael Foukarakis' answer for more about compilation. Also, see this excellent article from DDJ: "Multiple Inheritance Considered Useful" about how to do this correctly.