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;
}
输出I得到的是:
Entered f()!
Default C called!
CC called!
由于f()
由返回值,则它应该返回一个暂时的。由于T a = x;
是T a(x);
,是不是要求a
建设的拷贝构造函数,使用临时传入作为参数?
解决方案
由于
f()
由返回值,则它应该返回一个暂时的。由于T a = x;
是T a(x);
,是不是要求a
建设的拷贝构造函数,使用临时传入作为参数?
查找返回值优化。这是默认开启。如果你是在Windows上使用MSVC 2005+可以使用/Od
关闭这个功能,并得到想要的结果(或GCC -fno-elide-constructors
)。此外,对于MSVC看到这文章。
<强> 12.8复制类对象强>
<强> 15 :当满足特定条件时,一个 实现是允许省略 复制一个类对象的结构, 即使拷贝构造函数和/或 析构函数为对象具有侧 效果。在这种情况下, 实施将源和 靶向省略复制操作的 因为根本就是两个不同的方式 指代相同的对象,并且 该对象的破坏发生在 时代后,当这两个 对象必须 被摧毁,而不 optimization.115一份,省音 操作被允许在 下列情况下(其可以是 组合以消除多个 份):
- 在返回在一份声明 与类返回类型功能,强> 当表达式是一个的名称 与非挥发性自动对象 相同CV-不合格类型作为 函数返回类型,拷贝 操作可以通过省略 构成自动对象 直接进入函数的返回 值 - 当在一抛表达, 操作数是一个名 非易失性自动目的, 从操作到操作复制 异常对象(15.1),可以省略 通过构建自动对象 直接进入异常对象
- 当具有一个临时的类对象 没有被结合到一个参考(12.2) 将被复制到一个类对象与 同样的CV-不合格的类型,拷贝 操作可以通过省略 构建临时对象 直接进入的目标 省略复制
- 当 异常的异常声明 处理程序(第15)中声明的对象 相同类型的(除 CV-资质)作为异常 对象(15.1),在复制操作罐 通过处理被省略 异常声明为的别名 如果意义的异常对象 该计划将是不变的除外 对构造的执行和 为对象的析构函数的声明 例外声明。
注意:重点矿
其他提示
这是的的返回值优化(RVO)功能,你的编译器支持。
的示例一个拷贝构造函数可能不会当您返回值被调用。
在使用GCC -fno-elide-constructors
选项关闭该功能。
我相信这就是所谓的返回值优化。
我假定当f()
返回C
的对象是在调用方法因此没有复制需要初始化C a
的堆栈空间分配的对象。这是你的default C called
。
C b = a
这导致拷贝构造因此你CC called
。
顺便说一句,在wiki上的例子看起来挺像类似代码。