C++复制构造函数、临时对象和复制语义
对于这个程序,
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!\n"; }
C(const C &rhs) { cout << "CC called!\n"; }
};
const C f()
{
cout << "Entered f()!\n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
我得到的输出是:
Entered f()!
Default C called!
CC called!
由于 f()
按值返回,因此它应该返回一个临时值。由于 T a = x;
是 T a(x);
,它不会调用复制构造函数来构造 a
,临时传入作为其参数?
For this program
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!\n"; }
C(const C &rhs) { cout << "CC called!\n"; }
};
const C f()
{
cout << "Entered f()!\n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
the output I get is:
Entered f()!
Default C called!
CC called!
Since f()
is returning by value, it should return a temporary. As T a = x;
is T a(x);
, wouldn't it call the copy constructor for the construction of a
, with the temporary passed-in as its argument?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是您的编译器支持的返回值优化(RVO)功能的示例。
当您按值返回时,复制构造函数可能不会被调用。
在 GCC 上使用
-fno-elide-constructors
选项来关闭该功能。This is an example of Return Value Optimization(RVO) features which your compiler supports.
A copy constructor might not be called when you return by value.
Use
-fno-elide-constructors
option on GCC to turn that feature off.我相信它被称为返回值优化。
我假设当
f()
返回C
对象,该对象在调用方法的堆栈空间中分配,因此不需要复制来初始化C a
。这是您的默认 C 调用
。这会导致复制构造函数,因此您的
CC 被调用
。顺便说一句,维基百科上的示例看起来与您的代码非常相似。
I believe it's called return value optimization.
I assume when
f()
returnsC
object the object is allocated in the stack space of the calling method therefore no copy is required to initializeC a
. This is yourdefault C called
.This causes a copy constructor hence your
CC called
.Btw, the example on wiki looks quite like similar to your code.
查找返回值优化。默认情况下此功能处于打开状态。如果您在 Windows 上使用 MSVC 2005+,则可以使用
/Od
关闭此功能并获得所需的结果(或在 GCC 上使用-fno-elide-constructors
)。另外,对于 MSVC,请参阅此文章。Look up Return Value Optimization. This is turned on by default. If you are on Windows using MSVC 2005+ you can use
/Od
to turn this off and get the desired result (or-fno-elide-constructors
on GCC). Also, for MSVC see this article.