我有下面的代码,我对输出有点困惑:
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;
}
输出为:X 1
有人能解释一下这是怎么发生的吗?为什么C()ctor x = 3会改变B::x而不是A::x?它只有一个父类A吗?即使它定期继承B类。
2条答案
按热度按时间6rqinv9w1#
这有点棘手。这里的关键词是优势。举一个简单的例子:
这里,很明显,赋值
x = 3;
赋值给B
中的x
,因为当编译器在B
中看到x
时,名称查找停止,并且它不会在A
中查找另一个x
。在问题中的例子中,也有一个直接继承自
A
:现在仍然有两个不同的
x
对象:一个在B
中,一个在A
中,乍一看,在C::C()
中提到x
看起来很模糊:它是来自C
的基B
的那个还是来自C
的基A
的那个?显性规则表示
B
的x
版本隐藏了A
的版本,即使A
是C
的直接基。基本上,规则是,由于A::x
隐藏在继承链的一个分支中,因此它隐藏在所有分支中。形式上,当使用虚基类时,隐藏声明可以沿着不通过隐藏声明的子对象网格的路径到达。这不是二义性。
这仅适用于作为虚拟基的
A
:这里,
x
是不明确的;它可以表示B::x
,也可以表示A::x
(但不是B
的虚拟基中的A::x
)。l2osamch2#
C
的构造函数正在为B
的成员变量x
赋值,而不是A
的成员变量,print
方法来自A
类,即访问A
的x
成员变量值,即1
。希望这能回答你的问题。