在C++中初始化对象(类或结构的实例)可以通过各种方式进行。有些语法唤起对象的direct-initialization,而另一些语法则导致copy-initialization.在编译器中启用复制省略后,两者的性能相同.在禁用了复制-省略之后,当您选择后一个实例(复制初始化)时,每个实例都会有一个额外的复制/移动构造函数调用。
结论:复制初始化可以有性能惩罚!
从以下问题:我可以得出结论,这是copy-initialization语法:C++11成员初始化列表还是类内初始化程序?:
obj s = obj("value");这将是direct-initialization语法:
obj s{"value"};但是这个呢:
obj s = {"value"};而这个:
obj s = obj{"value"};而这个:
obj s("value");或者这个:
obj s = "value";注意事项
Bjarne在他的书“编程、原则和使用C++的实践”第二版第311页第9.4.2节中比较了几种初始化风格(但不是全部):
结构日期{ int y,m,d;//年份,月,日日期( int y,int m,int d);//检查有效日期并初始化无效add_day(int n);//将日期增加n天}; ..。 日期my_birthday;//错误:今天my_birthday未初始化日期{12,24,2007};//oops!运行时错误日期最后一次{2000,12,31};//OK (口语样式) next = {2014,2,14};//也确定(稍微冗长)日期圣诞节=日期{1976,12,24};//也确定(详细样式)
Stroustrup先生将这些不同的初始化样式表示为相等。至少在我看来是这样的。尽管如此,仍然有可能一些是direct-initialization,另一些是copy-initialization,,因为这些术语还没有在书中讨论过。
编辑
给出的答案带来了一些有趣的东西。
显然,这是direct-initialization
obj s("value");这是direct-list-initialization
obj s{"value"};正如你们中的一些人所指出的,这是有区别的。它们究竟有什么不同呢?在非优化编译器的输出中,这种差异会明显吗?
发布于 2017-10-08 19:45:35
obj s=obj(“值”);
这是一个prvalue的直接初始化,然后用来复制初始化变量s。C++17的prvalue规则使s实际上直接初始化.
obj的{“值”};
我是direct-list-initialization.“清单”部分很重要。每当您为初始化对象应用大括号-init-列表时,您都在执行列表初始化。
obj ={“值”};
这是复制列表初始化。
obj =obj{“值”};
这是prvalue的直接列表初始化,然后用来复制初始化变量s.
obj s(“值”);
这是直接初始化。
obj s=“值”;
那是复制初始化。
Stroustrup先生将这些不同的初始化样式表示为相等。
他们在做同样的事情的意义上是平等的。但它们在技术上并不平等;复制列表初始化不能调用explicit构造函数。因此,如果选择的构造函数是explicit,代码将无法在复制列表初始化的情况下编译。
发布于 2017-10-08 19:18:50
您可以轻松地查找对这类问题的答案。尽管如此,简单的答案是,=意味着复制初始化。然而,T t={...};是复制列表初始化,它(除非大括号只包含一个T或从它派生的东西)不涉及副本!然而,它确实不允许使用非explicit构造函数.
https://stackoverflow.com/questions/46634869
复制相似问题