简体   繁体   English

多重继承

[英]Multiple inheritance

I have 2 base classes (B1 and B2) which are derived from common Base class(B), where they have a common variable (let: int x; from base B), in 1st base x=0 , in the 2nd base x=10 (default values given in B1,B2 constructors). 我有2个基类(B1和B2),它们来自公共基类(B),它们有一个公共变量(let: int x;来自基数B),第一个基数x=0 ,第二个基数x=10 (B1,B2构造函数中给出的默认值)。

Visually: 视觉:

class B
{
    int x;

protected:

    B(int x) : x{x}{}
};

class B1 : public B
{
protected:

    B1() : B(0){}
};

class B2 : public B
{
protected:

    B2() : B(10){}
};

Now if I derive one more class: 现在,如果我再推导一个类:

class D : virtual public B1, virtual public B2
{
public:

    D() : B1{}, B2{}{}
};

Here only one copy of x will be available as per virtual concept, now if I try to access x value with derived class object which instance of x I will get in O/p ( x=0 or x=10 ), and why? 这里只有一个x副本可用于虚拟概念,现在如果我尝试使用派生类对象访问x值,x的实例将在O / p( x=0x=10 )中得到,为什么?

In order to use virtual inheritance, base B must be declared as virtual in both B1 and B2 . 为了使用虚拟继承,必须在B1B2中将基数B声明为虚拟。 Without that, you have non-virtual inheritance of B. 没有它,你有B的非虚拟继承。

If you have non-virtual inheritance, then you have two B bases in D , so you can't access x in D without qualifying it as B1::x or B2::x 如果你有非虚拟继承,那么你在D有两个B基,所以你不能在D访问x而不将其限定为B1::xB2::x

If you have virtual inheritance, then you only have one B and one x , so the two assignments to it ( x=0 and x=10 ) will happen in whichever order you did them in, and whichever one was later will overwrite the value set by the earlier one (much as with a simple variable x with two assignments). 如果你有虚拟继承,那么你只有一个B和一个x ,所以它的两个赋值( x=0x=10 )将按你执行的顺序发生,而后者中的任何一个都将覆盖该值由前一个设置(与具有两个赋值的简单变量x )。

In your setup as you have it, B is not actually inherited virtually, because you would have to declare virtual inheritance for B in both B1 and B2 (it always has to happen at the lowest level if the two "branches" are expected to be merged higher up in the class inheritance hierarchy), ie 在您的设置中, B实际上并不是虚拟继承的,因为您必须在B1B2声明B虚拟继承(如果预期两个“分支”预期,它总是必须发生在最低级别)在类继承层次结构中合并得更高,即

class B1 : virtual public B
{
protected:

    B1() : B(0){}
};

class B2 : virtual public B
{
protected:

    B2() : B(10){}
};

If you do that, initialization of B would be completely different, because there are special rules for the construction of virtual base classes: 如果这样做, B初始化将完全不同,因为构建虚拟基类有特殊规则:

In virtual inheritance, the virtual base class is always initialized by the most derived class . 在虚拟继承中,虚拟基类始终由派生程度最高的类初始化。 Thus, as you have implemented the constructor of D as 因此,正如您已经将D的构造函数实现为

D() : B1(), B2(){}

and therefore don't call your B constructor explicitly, the compiler will assume that you want to call B s default constructor. 因此,不要显式调用您的B构造函数,编译器将假定您要调用B的默认构造函数。 But your class B does not have a default constructor, so you would get a compiler error like this: 但是你的B类没有默认的构造函数,所以你会得到一个像这样的编译器错误:

prog.cpp: In constructor ‘D::D()’:
prog.cpp:31:20: error: no matching function for call to ‘B::B()’
     D() : B1(), B2(){}
                    ^

Therefore, you would have to do something like 因此,你必须做类似的事情

class D : public B1, public B2
{
public:

    D() :  B(99), B1(), B2(){}
};

and this also solves your question: The value of x will be whatever the most derived class wants it to be (99 in this case). 这也解决了你的问题: x的值将是大多数派生类想要的值(在这种情况下为99)。 Thus, there is no ambiguity. 因此,没有歧义。

PS: You also see, your question is at the heart of why it makes sense to have the special rule about virtual base class construction by the most derived class. PS:你也看到,你的问题是为什么有最大派生类的虚拟基类构造的特殊规则是有意义的核心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM