Ogu*_*guk 12 c++ gcc initializer-list c++11
请考虑以下代码,其中B
是D
通过B1
和继承的虚拟基类B2
:
#include <iostream>
class B
{
protected:
int x;
protected:
B(int x) : x{x}{std::cout << x << std::endl;}
};
class B1 : virtual public B
{
protected:
B1() : B(0){}
};
class B2 : virtual public B
{
protected:
B2() : B(10){}
};
class D : public B1, public B2
{
public:
D() : B(99), B1(), B2() {}
void print() {std::cout << "Final: " << x << std::endl;}
};
int main() {
D d;
d.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
见工作示例这里.我在B
构造函数中使用了输出,之后D
完全构造了以跟踪正在发生的事情.当我使用g ++ - 4.8.1编译上面的例子时,一切正常.它打印
99
Final: 99
Run Code Online (Sandbox Code Playgroud)
因为B
s构造函数从最派生的类(D
)调用一次,并且还确定了最终的值x
.
现在出现了奇怪的部分:如果我改变了这条线
D() : B(99), B1(), B2() {}
Run Code Online (Sandbox Code Playgroud)
到新的统一初始化语法,即
D() : B{99}, B1{}, B2{} {}
Run Code Online (Sandbox Code Playgroud)
奇怪的事发生了.首先,它不再编译,错误
prog.cpp: In constructor ‘D::D()’:
prog.cpp:17:5: error: ‘B1::B1()’ is protected
B1() : B(0){}
^
prog.cpp:31:27: error: within this context
D() : B{99}, B1{}, B2{} {}
Run Code Online (Sandbox Code Playgroud)
(并且相同B2
,见,这里)因为我在派生类中使用它没有意义,所以protected
应该没问题.如果我纠正了这个并且使构造函数B1
和B2
public而不是protected,那么一切都会变得混乱(参见这里),因为输出变为
99
0
10
Final: 10
Run Code Online (Sandbox Code Playgroud)
所以,事实上,初始化的B1
s和B2
s构造函数的B
部分仍然被执行,甚至改变了它的值x
.这不应该是虚拟继承的情况.请记住,我唯一改变的是
B1
和B2
classname{}
在成员初始化列表中使用语法D
而不是classname()
.我不敢相信这个基本的东西在gcc中出错了.但我在我的本地机器上用clang测试它,在那里,所有三种情况都按预期编译和运行(即像上面的第一个例子).如果它不是一个错误,有人可以指出我错过了什么?
编辑:我的第一次搜索没有提出,但现在我发现了另一个问题,至少显示受保护/公共错误.但是,这是gcc-4.7,所以我原本预计它会在gcc-4.8中处理.那么,我是否应该总结一下初始化列表在gcc中根本搞砸了!?
我不知道现在回答这个问题是否太晚了,但是你的代码在 GCC 4.9.2 中编译得很好!
~$g++ -std=c++11 test.cpp
~$./a.out
99
Final: 99
~$gcc --version
gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)