团队成员建议使用这样的初始化器:
return Demo{ *this };
Run Code Online (Sandbox Code Playgroud)
比以下更好:
return Demo(*this);
Run Code Online (Sandbox Code Playgroud)
假设一个像这样的简单类:
class Demo {
public:
int value1;
Demo(){}
Demo(Demo& demo) {
this->value1 = demo.value1;
}
Demo Clone() {
return Demo{ *this };
}
};
Run Code Online (Sandbox Code Playgroud)
我承认以前没有看过{ *this }语法,也找不到足够好的解释,以便我理解这两个选项的不同之处.是否有性能优势,语法选择或更多内容?
Ste*_*eve 16
你的同事错过了"统一初始化"的技巧,知道时不需要输入类型名称.例如,在创建返回值时. Clone可以定义为:
Demo Clone() {
return {*this};
}
Run Code Online (Sandbox Code Playgroud)
这将Demo根据需要调用复制构造函数.无论你认为这是好还是坏,都取决于你.
在GOTW 1 Sutter中指出:
指南:更喜欢使用{}进行初始化,例如向量v = {1,2,3,4}; 或者自动v =向量{1,2,3,4} ;,因为它更一致,更正确,并且避免必须知道旧式陷阱.在单参数情况下,您更喜欢只看到=符号,例如int i = 42; 和自动x =任何东西; 省略括号是好的....
特别是,使用大括号可以避免混淆:
Demo d(); //function declaration, but looks like it might construct a Demo
Demo d{}; //constructs a Demo, as you'd expect
Run Code Online (Sandbox Code Playgroud)
大括号语法将使用一个构造函数,该构造函数首先获取初始化列表(如果存在).否则它将使用普通的构造函数.它还可以防止上面列出的烦恼解析的可能性.
使用复制初始化时也有不同的行为.用标准的方式
Demo d = x;
Run Code Online (Sandbox Code Playgroud)
编译器可以选择在必要时转换x为a Demo,然后将转换后的r值移动/复制到w.类似于Demo d(Demo(x));意味着调用多个构造函数的东西.
Demo d = {x};
Run Code Online (Sandbox Code Playgroud)
这相当于Demo d{x}并保证只调用一个构造函数.由于上述两个赋值都不能使用显式构造函数.
正如评论中所提到的,存在一些陷阱.使用initializer_list具有"正常"构造函数的类会导致混淆.
vector<int> v{5}; // vector containing one element of '5'
vector<int> v(5); // vector containing five elements.
Run Code Online (Sandbox Code Playgroud)
这只是调用复制构造函数的另一种语法(实际上,用于调用构造函数,将大括号中的内容作为参数,在本例中为复制构造函数).
就个人而言,我会说它比以前更糟,仅仅是因为它做同样的事情......它只依赖于C++ 11.因此它增加了依赖性而没有任何好处.但你的里程可能会有所不同 你必须问你的同事.