我有以下代码,我对输出有点困惑:
class A{
protected:
int x;
public:
A() { x = 1; }
void print() { cout << "X: " << x << endl; }
};
class B: virtual public A{
protected:
int x;
public:
B() { x = 2; }
};
class C: virtual public A, public B {
public:
C() { x = 3; }
};
int main() {
C c;
c.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出为:X 1
有人可以解释一下这是如何发生的过程吗?为什么 C() ctor x = 3 改变 B::x 而不是 A::x?它只有一个父类 A 吗?尽管它定期继承B类
这有点棘手。这里的关键术语是统治力。举一个更简单的例子:
struct B: virtual A {
int x;
};
struct C : B {
C() { x = 3; }
};
Run Code Online (Sandbox Code Playgroud)
在这里,显然,赋值x = 3;分配给了xin B,因为当编译器看到 inx并且B不查找A另一个时,名称查找就会停止x。
在问题的示例中,还有来自的直接继承A:
struct C : B, virtual A {
C() { x = 3; }
};
Run Code Online (Sandbox Code Playgroud)
现在仍然有两个不同的x对象:一个 inB和一个 in A,乍一看,xin的提及C::C()看起来模棱两可:它是来自C's base 的那个B还是来自C's base的那个A?
支配规则表示,B该版本是xhidesA版本的版本,尽管它A是 的直接基础C。基本上,规则是,由于A::x沿继承链的一个分支隐藏,因此它沿所有分支隐藏。正式地,
当使用虚拟基类时,可以沿着不经过隐藏声明的子对象晶格路径到达隐藏声明。这并不是含糊之处。
这仅适用于A虚拟基数:
struct C : B, A {
C() { x = 3; }
};
Run Code Online (Sandbox Code Playgroud)
这里,x是含糊不清的;它可能意味着B::x或者它可能意味着A::x(但不是A::x在虚拟基中B)。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |