问题
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
A1beforeA2inAA2's constructor, butA2will be initialized beforeA1(because it is a virtual base andA1is not). - I put
AA1beforeAA2inB's constructor, butAA2will be initialized first (same reason).
来源:https://stackoverflow.com/questions/42319938/virtual-base-classes-order-of-creation