4

我有以下问题:

struct A1 {
    A1() { std::cout << "A1, "; }
};

struct A2 {
    A2() { std::cout << "A2, "; }
};

struct AA1 : virtual A1,  A2 {
    AA1() { std::cout << "AA1, "; }
};

struct AA2 : A1, virtual A2 {
    AA2(){ std::cout << "AA2, "; }
};

struct B : AA1, virtual AA2 {
    B() { std::cout << "B "; }
};

int main() {
    B b;
}

当您运行此代码时,答案是:

A1 A2 A1 AA2 A2 AA1 B

我想了解第一个A1创建的位置。

我知道在非虚拟类之前调用​​虚拟类的规则,但是第一个 A1 是困扰我的问题。

4

2 回答 2

2

第一个A1结果是初始化 的(非虚拟)基础的(虚拟)AA1基础B

的所有虚基B首先被初始化,它们依次是A1A2AA2。(AA2结果的初始化在输出中A1 AA2。)然后是直接基,其中只有一个,AA1(其初始化打印A2 AA1),最后是类本身,打印B。首先是所有虚拟基地,然后是其余的非虚拟基地。

于 2017-02-18T19:57:29.813 回答
2

B具有三个虚拟基类:A1A2AA2,并根据它们出现的顺序,按此顺序初始化它们。

你看到的第一个是初始化虚拟基础A1and ,但最后一个虚拟基础有一个非虚拟基础,所以在构造之前,你需要构造另一个,这就是为什么你之前有另一个。A2A1A2AA2A1AA2A1A1AA2

您可以通过运行以下代码段来可视化这一点:

#include <iostream>

struct A1 {
    A1(const char *s) { std::cout << "A1(" << s << ")\n"; }
};

struct A2 {
    A2(const char *s) { std::cout << "A2(" << s << ")\n"; }
};

struct AA1 : virtual A1,  A2 {
    AA1(const char *s) : A1("AA1"), A2("AA1") { std::cout << "AA1(" << s << ")\n"; }
};

struct AA2 : A1, virtual A2 {
    AA2(const char *s) : A1("AA2"), A2("AA2") { std::cout << "AA2(" << s << ")\n"; }
};

struct B : AA1, virtual AA2 {
    B() : A1("B"), A2("B"), AA1("B"), AA2("B") { std::cout << "B()\n"; }
};

int main() {
    B b;
}

这将输出:

A1(B)
A2(B)
A1(AA2)
AA2(B)
A2(AA1)
AA1(B)
B()

您还可以注意到,此代码会向您发出警告,因为:

  • 我把A1beforeA2放在AA2的构造函数中,但是A2会在 before 被初始化A1(因为它是一个虚拟基础而A1不是)。
  • 我把AA1beforeAA2放在B的构造函数中,但AA2会先初始化(同样的原因)。
于 2018-02-05T16:31:14.513 回答