同一个类你能继承两次吗

Can you inherit the same class twice?

本文关键字:两次 继承 同一个      更新时间:2023-10-16

同一个类可以继承两次吗?例如:

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

是的,它是合法的,不,对Base没有任何限制。

但是,您应该注意,这会导致Baz中存在两个类型为Base的不同对象,这将要求您在尝试访问其成员时使用限定名称来告诉C++您指的是Base的哪个版本。

C++提供了一种称为虚拟继承的机制来解决这个问题(如果这对你来说是个问题):

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

这将在Baz 内的FooBar对象之间共享Base对象

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

Baz类的语法是正确的。

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

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

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

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

那么通常有必要从这种重复的基础上对某个东西的任何使用进行限定。

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

是的,这是合法的,但具有同一基类的两个子对象会造成许多困难,因为您总是必须使用作用域运算符::明确地说出您想要的子对象。

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::
在虚拟示例中,您可以,因为使用Bar也可以访问该子对象,并且最可访问的路径决定了访问权限。

这是合法的。但是,当类在它之前被标记为受保护类和私有类时,就会出现限制。为此,它各自的函数和属性都是受保护的和私有的。