你可以两次继承同一个班吗?

时间:2014-04-22 22:22:48

标签: c++

你可以两次继承同一个班级吗?例如。 :

class Base {

};

class Foo : public Base {

};

class Bar : public Base {

};

class Baz : public Foo, public Bar { 
    //is this legal? 
    // are there restrictions on Base 
    //       (e.g. only virtual methods or a virtual base)?

};

5 个答案:

答案 0 :(得分:10)

是的,这是合法的,Base没有限制。

但是,您应该知道这会导致Base中存在两个Baz类型的不同对象,这将要求您使用限定名称来告诉C ++ Base哪个版本的class Base { }; class Foo : public virtual Base { }; class Bar : public virtual Base { }; class Baz : public Foo, public Bar { }; 意思是,当你试图访问其成员时。

C ++提供了一种名为virtual inheritance的机制来解决这个问题(如果这对你来说是个问题):

Base

这将在Foo

中的BarBaz个对象之间共享{{1}}个对象

答案 1 :(得分:1)

C ++确实支持多重继承。

Baz类的语法是正确的。

有关一些警告和更多信息,请参阅本教程:http://www.cprogramming.com/tutorial/multiple_inheritance.html

答案 2 :(得分:0)

是的,它是合法的,但是有两个相同Base类的子对象会导致很多困难,因为你总是必须使用范围运算符::明确说出你想要的那个。

Baz x;
Base& y = x; // Illegal because ambiguous.
Base& y = (Bar&)x; // Now unambiguous.

部分问题可以通过使用虚拟继承继承Base来解决,这确保只存在一个Base。子对象。
在这种情况下,在所有非虚拟基础之前,虚拟基础始终由最派生的构造函数初始化。

class Base {}
class Foo : public virtual Base {}
class Bar : public virtual Base {}
class Baz : public Foo, public Bar {}

Baz x;
Base& y = x; // Legal, because even though both direct bases inherit from `Base`,
// they do so virtually, thus there is only one Base subobject
Base& y = (Bar&)x; // Still unambiguous.

现在,如果Foo使用了受保护或私有继承,则无法在第一个(非虚拟)示例中强制转换为Baz中的Foo :: Derived或完全外部。
在虚拟示例中,您可以,因为该子对象也可以使用Bar访问,并且最易访问的路径决定了访问权限。

答案 3 :(得分:0)

是的,两次继承同一个班是合法的。

如果继承是非虚拟的,如在您的示例中(我只修复了语法和格式),

class Base {};
class Foo : public Base {};
class Bar : public Base {};

class Baz : public Foo, public Bar {};

然后通常有必要对这种重复基础中的某些东西进行限定。

但是,如果公共库的每个直接继承都是虚拟的(使用关键字virtual),那么公共库只有一个公共子对象。这就是C ++中所谓的菱形模式继承。这有点棘手,例如因为它产生至少一个遍布非连续内存区域的子对象,并且它是负责初始化公共虚拟基础的最派生类。它还引入了一些低效率,并与一些编译器错误相关联。所以它很少使用,但有时它是必要的 - 例如,它可以模拟Java接口继承,它可以用来模拟Java final(在C ++ 11中不是必需的)。

答案 4 :(得分:0)

这是合法的。 但是,当类被标记为受保护且私有类在其之前时,会出现限制。为此,它的各自功能和属性受到保护和保密。