为什么必须由最派生的类构建虚拟基类
Why must virtual base classes be constructed by the most derived class?
以下代码不会编译:
class A {
public:
A(int) {}
};
class B: virtual public A {
public:
B(): A(0) {}
};
// most derived class
class C: public B {
public:
C() {} // wrong!!!
};
如果我在C
的构造函数初始化列表中调用A
的构造函数,那就是:
// most derived class
class C: public B {
public:
C(): A(0) {} // OK!!!
};
它确实有效。
显然,原因是因为虚拟基类必须始终由最派生的类构建。
我不明白此限制背后的原因。
,因为它避免了这种情况:
class A {
public:
A(int) {}
};
class B0: virtual public A {
public:
B0(): A(0) {}
};
class B1: virtual public A {
public:
B1(): A(1) {}
};
class C: public B0, public B1 {
public:
C() {} // How is A constructed? A(0) from B0 or A(1) from B1?
};
,因为在类层次结构中具有几乎继承的基类,因此可以/可以通过多个类共享基类(例如,在钻石继承中,同一基类是由多个多个基础继承的课程(。这意味着,实际上只有一个基本类别的副本。从本质上讲,这意味着基类必须首先构建。最终意味着派生类必须实例化给定的基类。
例如:
class A;
class B1 : virtual A;
class B2 : virtual A;
class C: B1,B2 // A is shared, and would have one copy only.
我发现此规则容易出错且笨拙(但是,多个继承的哪一部分不是?(。
但是逻辑上施加的构造顺序必须与正常(非虚拟(继承的情况不同。考虑Ajay的示例,减去虚拟:
class A;
class B1 : A;
class B2 : A;
class C: B1,B2
在这种情况下,对于每个C两个,一个作为B1的一部分,另一个是B2的一部分。B类的代码是为此负责的,并且可以做到。事件的顺序是:
Start C ctor
Start B1 ctor
A ctor (in B's ctor code)
End B1 ctor
Start B2 ctor
A ctor (in B's ctor code)
End B2 ctor
End C ctor
现在考虑
中的虚拟继承class A;
class B1 : virtual A;
class B2 : virtual A;
class C: B1,B2
事件的一个顺序是
Start C ctor
A ctor // not B's code!
Start B1 ctor
// NO A ctor
End B1 ctor
Start B2 ctor
// NO A ctor
End B2 ctor
End C ctor
重要的逻辑区别在于,A型A类型AS 的几乎继承的基类子对象是最派生的类的一部分,并且在其控制下(此处 C
(。
B的构造函数一无所知,无法访问A
。因此,他们无法构造A
的子对象,包括基类。
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 无法在 CLion 中构建 C++ 项目
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何使用ndk-build.cmd构建Android.so文件
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- 如何在C++中获得"静态纯虚拟"功能?
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- C++无法定义虚拟函数 OUTER 类和头文件
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在虚拟机上使用 OpenCV 重新构建C++程序
- 为什么必须由最派生的类构建虚拟基类
- 如何在 conda 虚拟环境中安装 c++ 构建工具以与 cython/setproctitle 一起使用
- 如何在 VSCODE 中构建、运行和删除可执行文件和虚拟文件
- CMake 构建错误 - 虚拟方法错误缺少 vtable
- 读取使用COM0COM构建的虚拟串行端口的数据的问题
- Qt静态构建在虚拟机(win7 32位)上需要很长时间