【发布时间】:2017-08-10 11:45:21
【问题描述】:
C++ 示例代码:
class A {
public:
A(int) {}
};
class B : public virtual A {
public:
B(int b) : A(b) {}
};
class C : virtual public A {
public:
C(int c) : A(c) {}
};
class D : public B, public C {
public:
D() : B(1), C(2){};
};
这是菱形问题的典型代码(解决方案)。我知道为什么使用 virtual 关键字。但是我不知道编译器处理这个问题的内部机制。现在我遇到了关于上述机制的两种不同的理论,如下所述。
当使用 virtual 关键字继承类时,编译器会在派生类中添加一个虚拟基指针。我检查了派生类的大小,是的,它包括附加指针的大小。但是我不知道在上面的例子中,当类 A 的成员在类 D 中被引用时它指向哪里以及它是如何工作的。
-
编译器为每个构造函数创建程序员提供的每个定义的两个版本。从this link知道 例如在上面的代码中。 编译器会生成2个版本的C构造函数
C(int){} // Version1 C(int):A(int){} // Version2还有两个不同版本的构造函数B
B(int){} // Version1 B(int):A(int){} // Version2所以当 D 被构造时,编译器将生成以下任一代码
D() : B(), C(2) {} // Version1 D() : B(1), C() {} // Version2以确保只创建 A 的一个实例,从而避免 A 的重复副本。
请帮我了解一下内部机制。
【问题讨论】:
-
@Ron 请在标记之前阅读实际帖子
-
@paper.plane 这个问题对于 SO 来说可能有点理论性......另外,虚拟继承的实际实现取决于编译器......看看标准实际上说什么看看:@987654322 @ 在第 231 页
-
@Ron 再说一遍,我想你可能还没有读过这个问题,只是用谷歌搜索了标题...... op 似乎不想知道 virtual 做什么(或 virtual 基类做什么)而是如何以及为什么生成所述类和继承类的内部对象模型
-
“内部机制”依赖于编译器,因此为了让 Stack Overflow 标准能够回答这个问题,您需要通过指定特定的工具链来缩小范围。
-
一种选择是让编译器向
B(int)和C(int)传递一个秘密参数,告诉他们是否应该调用A(int)。语言标准只是告诉我们效果,而不是如何实现。
标签: c++ constructor virtual-inheritance language-implementation ctor-initializer