K.M*_*ier 2 c++ initialization initializer-list c++11 c++14
可以通过多种方式来初始化C ++中的对象(类或结构的实例)。某些语法引起对象的直接初始化,而其他语法则导致复制初始化。随着拷贝省音在编译器中启用,两者具有相同的性能。在禁用复制删除的情况下,当您为每个实例选择复制/初始化时,都会有一个附加的复制/移动构造函数调用(复制初始化)。
结论:复制初始化可能会降低性能!
来自以下问题:C ++ 11成员初始值设定项列表与类初始值设定项?我可以得出结论,这将是复制初始化语法:
obj s = obj("value");
Run Code Online (Sandbox Code Playgroud)
这将是直接初始化语法:
obj s{"value"};
Run Code Online (Sandbox Code Playgroud)
但是这个呢?
obj s = {"value"};
Run Code Online (Sandbox Code Playgroud)
还有这个:
obj s = obj{"value"};
Run Code Online (Sandbox Code Playgroud)
还有这个:
obj s("value");
Run Code Online (Sandbox Code Playgroud)
或者这个:
obj s = "value";
Run Code Online (Sandbox Code Playgroud)
注意
Bjarne Stroustrup在他的书“使用C ++编程,原理和实践”第二版,第311页,第9.4.2节中比较了一些初始化样式(但不是全部):
Run Code Online (Sandbox Code Playgroud)struct Date { int y,m,d; //year, month, day Date(int y, int m, int d); //check for valid date and initialize void add_day(int n); //increase the Date by n days };...
Run Code Online (Sandbox Code Playgroud)Date my_birthday; //error: my_birthday not initialized Date today{12,24,2007}; //oops! run-time error Date last{2000,12,31}; //OK (colloquial style) Date next = {2014,2,14}; //also OK (slightly verbose) Date christmas = Date{1976,12,24}; //also OK (verbose style)
Stroustrup先生同样提出了这些不同的初始化样式。至少,这就是我的样子。不过,由于本书中尚未讨论这些术语,因此某些可能仍然是直接初始化的,而另一些则是复制初始化的。
编辑
给出的答案带来了一些有趣的东西。
显然,这是直接初始化:
obj s("value");
Run Code Online (Sandbox Code Playgroud)
这是直接列表初始化:
obj s{"value"};
Run Code Online (Sandbox Code Playgroud)
就像某些人指出的那样,两者之间存在差异。它们实际上有什么不同?在非优化编译器的输出中,差异是否明显?
Run Code Online (Sandbox Code Playgroud)obj s = obj("value");
这是一个纯右值的直接初始化,然后用于复制初始化变量s。C++17 的纯右值规则使s.
Run Code Online (Sandbox Code Playgroud)obj s{"value"};
这是直接列表初始化。“列表”部分很重要。任何时候为了初始化对象而应用花括号初始化列表时,都是在执行列表初始化。
Run Code Online (Sandbox Code Playgroud)obj s = {"value"};
这是复制列表初始化。
Run Code Online (Sandbox Code Playgroud)obj s = obj{"value"};
这是一个纯右值的直接列表初始化,然后用于复制初始化变量s。
Run Code Online (Sandbox Code Playgroud)obj s("value");
那就是直接初始化。
Run Code Online (Sandbox Code Playgroud)obj s = "value";
那就是副本初始化。
Stroustrup 先生将这些不同的初始化风格一视同仁。
他们在做同样的事情的意义上是平等的。但它们在技术上并不相等。复制列表初始化不能调用explicit构造函数。因此,如果选定的构造函数是explicit,则在复制列表初始化的情况下,代码将无法编译。
| 归档时间: |
|
| 查看次数: |
776 次 |
| 最近记录: |