3

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

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

我想应该是两个吧?第一个是 string(const char* s),第二个是 string(const string& s)。如果我错了,请纠正我。

下一个问题是,如果我在发布模式下编译代码,编译器会自动优化它吗?例如,将其视为std::string s("hello world");不同的编译器是否表现不同?

4

2 回答 2

4

源类型与目标类型相同的复制初始化(带有=)的行为非常类似于直接初始化。所以初始化等效于:

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

在没有优化的情况下,将按照您的描述调用两个构造函数。在 C++11 中,第二步(定义为string(string&&))将首选移动构造函数,因为 std::string("hello world")它是一个右值表达式。但是,该标准明确允许在某些情况下省略复制/移动,包括以下情况:

当尚未绑定到引用 (12.2) 的临时类对象将被复制/移动到具有相同 cv-unqualified 类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动

因此,编译器可以选择优化掉副本。请注意,即使复制构造函数有一些奇怪的副作用,编译器也可能会这样做。也就是说,一个定义完善且有效的 C++ 程序可能有多个可能的执行路径。通常,您希望避免这种情况。

于 2013-04-17T15:07:30.527 回答
3

您的代码符合复制省略的条件,因此大多数理智的编译器总是会这样对待,std::string s("hello world");除非明确指示不要这样做。

于 2013-04-17T15:06:10.080 回答