繁体   English   中英

多重继承

[英]Multiple inheritance

我有2个基类(B1和B2),它们来自公共基类(B),它们有一个公共变量(let: int x;来自基数B),第一个基数x=0 ,第二个基数x=10 (B1,B2构造函数中给出的默认值)。

视觉:

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){}
};

现在,如果我再推导一个类:

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

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

这里只有一个x副本可用于虚拟概念,现在如果我尝试使用派生类对象访问x值,x的实例将在O / p( x=0x=10 )中得到,为什么?

为了使用虚拟继承,必须在B1B2中将基数B声明为虚拟。 没有它,你有B的非虚拟继承。

如果你有非虚拟继承,那么你在D有两个B基,所以你不能在D访问x而不将其限定为B1::xB2::x

如果你有虚拟继承,那么你只有一个B和一个x ,所以它的两个赋值( x=0x=10 )将按你执行的顺序发生,而后者中的任何一个都将覆盖该值由前一个设置(与具有两个赋值的简单变量x )。

在您的设置中, B实际上并不是虚拟继承的,因为您必须在B1B2声明B虚拟继承(如果预期两个“分支”预期,它总是必须发生在最低级别)在类继承层次结构中合并得更高,即

class B1 : virtual public B
{
protected:

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

class B2 : virtual public B
{
protected:

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

如果这样做, B初始化将完全不同,因为构建虚拟基类有特殊规则:

在虚拟继承中,虚拟基类始终由派生程度最高的类初始化。 因此,正如您已经将D的构造函数实现为

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

因此,不要显式调用您的B构造函数,编译器将假定您要调用B的默认构造函数。 但是你的B类没有默认的构造函数,所以你会得到一个像这样的编译器错误:

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

因此,你必须做类似的事情

class D : public B1, public B2
{
public:

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

这也解决了你的问题: x的值将是大多数派生类想要的值(在这种情况下为99)。 因此,没有歧义。

PS:你也看到,你的问题是为什么有最大派生类的虚拟基类构造的特殊规则是有意义的核心。

暂无
暂无

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

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