是直接初始化还是复制初始化? [英] Is it direct-initialization or copy-initialization?
问题描述
可以使用各种方法来初始化C ++中的对象(类或结构的实例)。某些语法引起对象的直接初始化,其他语法导致复制初始化。在编译器中启用 copy-elision 时,两者的性能相同。禁用 copy-elision 时,在选择每个实例化(复制初始化)时,每个实例化都会有一个附加的copy / move构造函数调用。
Initializing objects (instances of classes or structs) in C++ can be done in various ways. Some syntaxes evoke a direct-initialization of your object, other syntaxes lead to a copy-initialization. With copy-elision enabled in the compiler, both have identical performance. With copy-elision disabled, there is an additional copy/move constructor call upon every instantiation when you choose for the latter (copy-initialization).
结论:复制初始化可能会影响性能!
Conclusion: copy-initialization can have a performance-penalty!
来自以下问题: C ++ 11成员初始值设定项列表与类初始值设定项?我可以得出结论,这将是复制初始化语法:
From the following question: C++11 member initializer list vs in-class initializer? I can conclude that this would be copy-initialization syntax:
obj s = obj("value");
这将是直接初始化语法:
obj s{"value"};
但是这个呢:
But what about this one:
obj s = {"value"};
而这个:
obj s = obj{"value"};
而这个:
obj s("value");
或者这一个:
obj s = "value";
注意
Bjarne Stroustrup在他的书使用C ++进行编程,原理和实践第二版,第311页,第9.4.2节中比较了几种初始化样式(但不是全部):
NOTE
Bjarne Stroustrup compares a few initialization styles (but not all) in his book "Programming, Principles and Practice Using C++" 2nd edition, on page 311, §9.4.2:
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
};
...
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将这些不同的初始化样式呈现为相等。至少,这就是我的样子。不过,由于本书中尚未讨论这些术语,因此有些仍然可能是直接初始化,而另一些是 copy-initialization 。
Mr. Stroustrup presents these different initialization styles as equal. At least, that's how it looks to me. Nevertheless, it could still be possible that some are direct-initialization and others copy-initialization, since those terms are not yet discussed at that point in the book.
编辑
给定的答案会带来一些有趣的结果。
显然,这是直接初始化:
obj s("value");
这是直接列表初始化:
obj s{"value"};
有些人指出,这是有区别的。它们实际上有什么不同?
As some of you point out, there is a difference. In what way do they actually differ? Would the difference be noticeable in the output of a non-optimizing compiler?
推荐答案
obj s = obj("value");
这是对prvalue的直接初始化,然后将其用于复制初始化变量 s
。 C ++ 17的prvalue规则实际上对 s
进行了直接初始化。
This is direct initialization of a prvalue, which is then used to copy initialize the variable s
. C++17's prvalue rules make this de-facto direct initialization of s
.
obj s{"value"};
这是直接- 列表 -初始化。 列表部分很重要。任何时候为了初始化对象而应用了支撑初始化列表,都在执行列表初始化。
This is direct-list-initialization. The "list" part is important. Anytime you apply a braced-init-list for the purposes of initializing an object, you are performing list-initialization.
obj s = {"value"};
这是复制列表初始化。
obj s = obj{"value"};
这是对prvalue的直接列表初始化,即然后用于复制初始化变量 s
。
This is direct-list-initialization of a prvalue, which is then used to copy initialize the variable s
.
obj s("value");
这是直接初始化。
obj s = "value";
这是副本初始化。
先生。 Stroustrup会以相同的方式呈现这些不同的初始化样式。
Mr. Stroustrup presents these different initialization styles as equal.
就它们在大多数情况下所做的相同而言,它们是相等的。但是他们在技术上并不平等;复制列表初始化不能调用 explicit
构造函数。因此,如果选择的构造函数是 explicit
,则在复制列表初始化的情况下代码将无法编译。
They are equal in the sense that they do mostly the same thing. But they're not technically equal; copy-list-initialization cannot call explicit
constructors. So if the selected constructor were explicit
, the code would fail to compile in the copy-list-initialization cases.
这篇关于是直接初始化还是复制初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!