Mem*_*ter 2 c++ constructor initialization initializer-list c++11
另一个C++问题,我试图弄清楚在构造对象时使用"="会产生什么影响.考虑:
class Foo {
private:
int bar;
int baz;
public:
Foo(int bar, int baz)
:bar(bar), baz(baz) {}
};
int main() {
Foo foo1{4, 2};
Foo foo2 = {4, 2};
Foo foo3 = Foo{4, 2}; // I prefer this one for aesthetic reasons.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有什么区别,我应该坚持哪种最佳做法?
此外,虽然我们讨论的是最佳实践的主题,但我听说添加explicit构造函数是一个好主意™因为隐式转换的奇怪行为.所以我添加explicit到构造函数Foo:
public:
explicit Foo(int bar, int baz)
:bar(bar), baz(baz) {}
Run Code Online (Sandbox Code Playgroud)
突然,这个:
Foo foo2 = {4, 2};
Run Code Online (Sandbox Code Playgroud)
无法编译错误:
error: chosen constructor is explicit in copy-initialization
Run Code Online (Sandbox Code Playgroud)
这是为什么?
有什么区别
Run Code Online (Sandbox Code Playgroud)Foo foo1{4, 2};
这是直接初始化(2).
在以下情况下执行直接初始化:
2)在列表初始化序列期间,如果没有提供初始化列表构造函数并且可以访问匹配的构造函数,则所有必要的隐式转换都是非缩小的.
Run Code Online (Sandbox Code Playgroud)Foo foo2 = {4, 2};
这是复制列表初始化(6).对于非直接列表初始化,不考虑显式构造函数.这解释了为什么在更改构造函数显式时程序没有编译.
copy-list-initialization(只能调用非显式构造函数)
6)在等号后用braced-init-list初始化命名变量
Run Code Online (Sandbox Code Playgroud)Foo foo3 = Foo{4, 2};
这是临时对象的直接列表初始化(2),然后从临时对象复制初始化(1).
direct-list-initialization(考虑显式和非显式构造函数)
2)使用braced-init-list初始化未命名的临时文件
在以下情况下执行复制初始化:
2)当声明非引用类型T的命名变量(自动,静态或线程局部)时,初始化器由等号后跟表达式组成.
首先是最简单的,这就是我喜欢它的原因.
第二个需要一个隐式构造函数,但在其他方面没有问题.
第三个涉及重复类型(违反DRY),并构造一个不必要的临时(实际上,优化器可能会删除副本,但类型必须是可复制的).
我听说为构造函数添加明确是一个好主意™.所以我向Foo的构造函数添加了显式
如果要阻止隐式转换,则向单个参数构造函数添加显式是个好主意.对于两个参数构造函数,显式并不是那么普遍有用,但我不怀疑可能存在需要它的情况.
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |