2013-04-17 177 views
3

我是C++编程的初学者,我有一个关于C++类构造函数的简单问题。 为以下代码片段调用构造函数多少次?构造函数被调用多少次?

std::string s = std::string("hello world"); 

我想这是两个,对吧?第一个是字符串(const char * s),第二个是字符串(常量字符串& s)。如果我错了,请纠正我。

接下来的问题是,如果我在释放模式下编译代码,编译器会自动优化它吗?例如把它当作std::string s("hello world");不同的编译器有不同的行为吗?

+0

检查C++ 11中的移动构造函数。 –

+0

C++ 03的行为是什么? –

回答

4

复制初始化(与=)其中源类型与目标类型相同的行为非常像直接初始化。因此,初始化相当于:

std::string s(std::string("hello world")); 

没有优化,将按您所述调用两个构造函数。在C++ 11中,移动构造函数将优先用于第二步(定义为string(string&&)),因为std::string("hello world")是一个右值表达式。然而,标准明确地允许在某些情况下拷贝/移动省音,包括这一个:

当尚未结合至参考(12.2)临时类对象将被复制/移动到一个类用相同的CV-非限定类型的对象中,复制/移动操作可以通过直接构建临时物体插入省略副本的目标可以省略/移动

因此,编译器可以,如果它选择,优化走复制。请注意,即使复制构造函数有一些奇怪的副作用,编译器也可能会这样做。也就是说,一个完美定义和有效的C++程序可能有多个可能的执行路径。一般来说,你想避免这种情况。

+0

为了迂回,它不是“完全一样”,因为隐式构造函数需要被复制初始化访问,并且原则上复制初始化允许编译器调用两个构造函数(实际上没有任何理性的编译器会这么做)。 –

+0

@KerrekSB对我而言,措辞不好。 “完全”改为“非常”。但是,这两种形式都可以调用两个构造函数,不是吗? –

+0

直接初始化可能*不*调用两个构造函数,我非常确定......实际上,非常确定,因为您可以删除复制构造函数并仍然执行直接初始化。 –

3

您的代码符合复制elision的条件,因此除非明确指示不要这样做,否则大多数理智编译器将始终如此对待,如std::string s("hello world");