@AfterAll
@DisabledIfSystemProperty(named = "runTearDownScript", matches = "false")
void clearDownTestEnvironment() {
System.out.println(System.getProperty("runTearDownScript"));
}
输出代码为:
这没有任何意义。对象D被构造两次。为何编译器不抱怨foo不明确? G如何知道foo上只有一个定义? (在这种情况下,D被创建了两次,我没有使用虚拟继承,但是以某种方式知道这一点。) 老实说,为了避免对foo的模棱两可,E和F实际上也应该是D固有的。 谁能提供一个很好的解释? 在VS 2017 Windows中编译。 您可以将这一继承行想象为 双重钻石问题。
答案 0 :(得分:4)
对象D被构造了两次。
这是因为对象具有两个D
基。一个通过E
,另一个通过F
。
为什么编译器不会抱怨foo是模棱两可的?
因为只有一个A
基。这是因为它是虚拟基础。每个具体实例始终只有一个其类型的虚拟基础子对象。
这是继承的粗略ASCII艺术:
non-virtual | virtual
| A
____________|__/
/ / / / |
B C B C |
\/ \/ |
D D |
\ / |
E F | bases
_____\/______________________
G concrete
编译器如何知道多个D应该包含相同的基数A
因为它知道所有这些A碱基都是虚拟的。
答案 1 :(得分:3)
这没有道理。
为什么?这正是虚拟继承的目的。 A
中只有一个G
子对象。当我们沿着层次结构向下移动时,说明符会停留,因此即使G
有两个D
,它们也共享一个A
。