virtual base class and initialization lists [duplicate]

Deadly 提交于 2019-12-09 03:41:40

问题


Possible Duplicate:
gcc c++ virtual inheritance problem

Hi all,

I'm wondering about how the compiler would handle different initialization values when using multiple inheritance from a virtual base class. Consider the notorious 'diamond of dread' inheritance scheme:

     Base
     / \
    /   \
  D1     D2
    \   /
     \ /
     Join

In order to avoid having two copies of Base in Join, I use virtual inheritance for D1 and D2 (see e.g. here). Now, lets say Base is not abstract, but has a member field, which is initialized in its constructor:

class Base { 
public:
    Base(int x_) {x = x_;};
    virtual ~Base(){};

public:
    int x;
};

class D1 : public virtual Base {
public:
    D1() : Base(1) {};
    virtual ~D1(){};
};

class D2 : public virtual Base {
public:
    D2() : Base(2) {};
    virtual ~D2(){};
};

class Join : public D1, public D2 {
public:
    Join(){};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;

   return 0;
}

Will the output be 1, 2, or is it compiler-dependent?


回答1:


It shoudn't compile. Virtual bases are initialized by the most derived class which is Join. Join doesn't explicitly initialize Base but Base has no accessible default constructor.

[It also won't compiler because definitions of classes need to be terminated with a ; but I've assumed that this is a typo. main should also return int and I've assumed that j.x is a typo for j->x.]




回答2:


When you have virtual inheritance it is the final class that must initialise the virtual base class.

Therefore the constructor of Join must construct Base:

   class Join : public D1, public D2 
    {
    public:
        Join() : Base(3){} // or whatever value
        ~Join(){}
    };

It is the exception to the rule that classes only normally initialise their immediate base-classes.

(Aside from that main should return int and you would need to do j->x not j.x as j is a pointer, as well as the fact you must delete it as you called new)




回答3:


Since the Base does not have an implicit constructor and both C1 and C2 are virtual bases, you would have to change it like this (and also add semicolons after the rest of the class declarations as pointed out by Charles Bailey)

class Join : public D1, public D2 {
public:
    Join() : Base(3) {};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;
}

Then it would print 3 to the standard output



来源:https://stackoverflow.com/questions/4849289/virtual-base-class-and-initialization-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!