c++ - 虚拟继承实际上是如何工作的?

标签 c++ inheritance virtual-inheritance

我知道菱形问题,但问题是 - 当我用谷歌搜索“虚拟继承”时,结果提到菱形问题。我想知道它一般是如何工作的,以及它与普通继承有何不同。

我知道当一个类(通常)从另一个类继承时,它只包含它的所有成员(字段和方法,不考虑访问级别)。其中一些可能会被新成员覆盖或隐藏,但它们仍然存在。继承还定义了层次结构中的类之间的某些关系,这会影响转换和多态性。

虚拟继承有何不同?例如:

class A
{
    public:
    int a;
    int b;
    void fun(int x)
    {}
    void gun(int x)
    {}
};

class B : public A
{
    public:
    int a;
    int c;
    void fun(int x)
    {}
    void hun(int x)
    {}
};

class C : virtual public A
{
    public:
    int a;
    int c;
    void fun(int x)
    {}
    void hun(int x)
    {}
};

BC 有什么区别?还有我的示例没有利用的任何其他差异吗?标准怎么说?此外,如果 C++03 和 C++11 之间存在差异,请指出。

最佳答案

通过单一继承级别,行为没有区别。

区别在于从多个基类继承时,它们本身有一个共同的基类:

struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B,C {};

在这个例子中,通过虚拟继承,D 只包含一个 A 子对象,它的 BC 子对象共享;这是“菱形”图案:

    A
   / \
   B C
   \ /
    D

如果没有虚拟继承,它将包含两个 A 子对象,并且没有“钻石”:

   A A
   | |
   B C
   \ /
    D

有或没有多重继承,如果你有不止一层的继承,还是有区别的:虚基类必须由最派生的类初始化,而不是由它的直接派生类初始化。这是为了避免在多重继承的情况下出现歧义,其中(在上面的示例中)BC 否则将负责初始化共享的 A

关于c++ - 虚拟继承实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26509757/

相关文章:

c++ - 在多态性增加派生类大小的多重继承的情况下,在派生类中为析构函数编写代码。为什么?

c++ - 内存计数器 - 碰撞检测项目

c++ - 如何与另一个继承类的继承类对话

c++ - 在派生类接口(interface)中隐藏基类的特定功能

c++ - QT C++ - 类问题等到信号被处理并返回数据

c++ - 在 C++ 中使用 char 的新运算符

java - 没有getter方法就不能使用对象变量

java - Stack OverFlow 与继承的 JPanels

c++ - 当 key 是涉及虚拟继承的基类指针时,访问 std::unordered_map 项会崩溃

c++ - 基数到派生到构造函数中的另一个基数转换段错误 - 无效代码或编译器错误?