考虑一下这段代码:
#include <iostream>
class A {
public:
A(int s) { std::cout << "A(" << s << ")\n"; }
};
class B1 : virtual public A {
public:
B1(int s1, int s2)
: A{s1} { std::cout << "B1(" << s1 << "," << s2 << ")\n"; }
};
class B2 : virtual public A {
public:
B2(int s1, int s2)
: A{s1} { std::cout << "B2(" << s1 << "," << s2 << ")\n"; }
};
class C1 : public B1, public B2 {
public:
C1() : B1{1,2}, B2{3,4}, A{5} {}
};
class C2 : public B1, public B2 {
public:
C2() : B1(1,2), B2(3,4), A{5} {}
};
int main()
{
std::cout << "Create c1:\n";
C1 c1;
std::cout << "\n";
std::cout << "Create c2:\n";
C2 c2;
}
A类是B1和B2的虚拟基类.类C1和C2是相同的,除了C1使用{…}并且C2使用(…)来构造B1和B2.
由于此处使用的虚拟继承,因此应将A类构造为C1或C2构造的一部分.
如果我使用Microsoft VS2015编译此代码,它会在运行时生成此输出:
Create c1:
A(5)
B1(1,2)
B2(3,4)
Create c2:
A(5)
B1(1,2)
B2(3,4)
这正是我所期待的.
但是如果我用GCC(6.1.0)编译它会产生这个输出:
Create c1:
A(5)
A(1)
B1(1,2)
A(3)
B2(3,4)
Create c2:
A(5)
B1(1,2)
B2(3,4)
这里,在构造c1时,A的构造函数被调用三次,但在构造c2时只调用一次.
这是GCC中的一个错误还是我误解了一些东西?
最佳答案 回答我自己的问题:
显然,GCC在这种情况下确实存在错误.使用GCC 7.0.0版编译代码会使用此输出生成正确的行为:
Create c1:
A(5)
B1(1,2)
B2(3,4)
Create c2:
A(5)
B1(1,2)
B2(3,4)