2010-02-03 87 views

回答

26

是和

首先是明确初始化号,第二个是拷贝初始化。该标准允许用第一个替换第二个。实际上,生成的代码是相同的。

下面是简而言之会发生什么:

std::string s1("foo"); 

形式的字符串构造:

string (const char * s); 

被调用s1

在第二种情况下。创建一个临时对象,并为该临时对象提供所述的构造函数。然后,复制构造函数被调用。例如:

string s1 = string("foo"); 

在实践中,第二种形式被优化,成为第一种形式。我还没有看到一个不优化第二种情况的编译器。

+0

拷贝构造函数不会在第二种情况下被调用,只会调用字符串(const char * s)。这是复制初始化。检查:[how-c-implicitly-convert-c-style-string-to-a-string-object](http://stackoverflow.com/questions/35568612/how-c-implicitly-convert-c-style-字符串到字符串对象) – expoter 2016-02-23 05:36:09

-5

第一个比较好。

第二个将创建实例并将分配默认值(“”)。然后会有一个secodn分配:“foo”。 所以2的作业,而不是1 ...

+7

不,第二个不会调用赋值运算符。 – 2010-02-03 13:48:32

13

表面上,第一个调用const char*构造函数来初始化s1。第二个使用const char*构造函数初始化一个临时值,然后使用复制构造函数传入对该临时值的引用,以初始化s2

然而,标准明确允许所谓的“复制省略”,这意味着,阿拉克说,第二个可以合法地与第一更换,即使拷贝构造函数具有可观察到的副作用,这样的变化影响程序的输出。

但是,当这个替换完成后,编译器仍然必须检查该类是否有可访问的拷贝构造函数。所以一个潜在的区别是第二种形式需要一个拷贝构造函数来调用,即使编译器不需要调用它。很明显std::string确实有一个,所以在这种情况下,这并没有什么区别,但对于其他类可以。

+1

你得到了我的+1“标准明确允许所谓的”复制elision“;) – AraK 2010-02-03 14:03:09

+0

小招供:在发布后,我注意到它是在索引中的”复制构造函数elision“,但据我记得我已经提到它作为“复制elision”:-) – 2010-02-03 18:04:53