c++ 如果两个顶点都虚拟地但有规律地继承第三个顶点,那么虚拟继承三角形是如何工作的?

xoshrz7s  于 2023-03-25  发布在  其他
关注(0)|答案(2)|浏览(95)

我有下面的代码,我对输出有点困惑:

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类。

6rqinv9w

6rqinv9w1#

这有点棘手。这里的关键词是优势。举一个简单的例子:

struct B: virtual A {
    int x;
};

struct C : B {
    C() { x = 3; }
};

这里,很明显,赋值x = 3;赋值给B中的x,因为当编译器在B中看到x时,名称查找停止,并且它不会在A中查找另一个x
在问题中的例子中,也有一个直接继承自A

struct C : B, virtual A {
    C() { x = 3; }
};

现在仍然有两个不同的x对象:一个在B中,一个在A中,乍一看,在C::C()中提到x看起来很模糊:它是来自C的基B的那个还是来自C的基A的那个?
显性规则表示Bx版本隐藏了A的版本,即使AC的直接基。基本上,规则是,由于A::x隐藏在继承链的一个分支中,因此它隐藏在所有分支中。形式上,
当使用虚基类时,隐藏声明可以沿着不通过隐藏声明的子对象网格的路径到达。这不是二义性。
这仅适用于作为虚拟基的A

struct C : B, A {
    C() { x = 3; }
};

这里,x是不明确的;它可以表示B::x,也可以表示A::x(但不是B的虚拟基中的A::x)。

l2osamch

l2osamch2#

C的构造函数正在为B的成员变量x赋值,而不是A的成员变量,print方法来自A类,即访问Ax成员变量值,即1
希望这能回答你的问题。

相关问题