Virtual base classes order of creation

狂风中的少年 提交于 2019-12-01 05:18:42

问题


I have the following problem:

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;
}

When you run this code, the answer is:

A1 A2 A1 AA2 A2 AA1 B

I want to understand where is the first A1 created.

I know the rule that the virtual classes are called before non - virtual classes but that first A1 is the problem that is bothering me.


回答1:


The first A1 results from the initialization of the (virtual) base of the (non-virtual) base AA1 of B.

All the virtual bases of B are initialized first, and they are, in order, A1, A2 and AA2. (The initialization of AA2 results in the output A1 AA2.) Then come the direct bases, of which there is only one, AA1 (whose initialization prints A2 AA1), and finally the class itself, printing B. All the virtual bases come first, and then only the remaining non-virtual ones.




回答2:


B has three virtual base classes: A1, A2 and AA2, and according to their order of appearance, it will initialize them in this order.

The first A1 and A2 you see are the initializing of the virtual base A1 and A2, but the last virtual base AA2 has a non-virtual base A1, so before constructing AA2, you'll need to construct another A1, which is why you have another A1 before AA2.

You can visualize this by running the following snippet:

#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;
}

This will output:

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

You can also notice that this code gives you warning because:

  • I put A1 before A2 in AA2's constructor, but A2 will be initialized before A1 (because it is a virtual base and A1 is not).
  • I put AA1 before AA2 in B's constructor, but AA2 will be initialized first (same reason).


来源:https://stackoverflow.com/questions/42319938/virtual-base-classes-order-of-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!