当我尝试返回函数中定义的局部变量时,我无法弄清楚为什么没有调用copy-constructor。请参阅以下简化示例:
#include <iostream>
using namespace std;
class X {
public:
X() { cout << "Default Constructor" << endl; }
X(const X&) { cout << "Copy Constructor" << endl; }
};
X f(X x) { return x; }
X g() {
X y;
return y;
}
int main() {
cout << "First create an object" << endl;
X a;
cout << "Call f()" << endl;
f(a);
cout << "Call g()" << endl;
g();
}
编制程序的输出如下
First create an object
Default Constructor
Call f()
Copy Constructor
Copy Constructor
Call g()
Default Constructor
我了解调用f()
时发生了什么,但不知道为什么调用return y
内的g()
不会触发复制构造函数。
答案 0 :(得分:5)
编译器优化了返回副本。这被称为NRVO(命名返回值优化)。
在具有类返回类型的函数的return语句中,当表达式是非易失性自动对象(函数或catch子句参数除外)的名称时,具有与函数相同的cv-unqualified类型返回类型,通过将自动对象直接构造到函数的返回值
中,可以省略复制/移动操作
即使复制构造函数有副作用,也允许编译器执行此操作。
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使该对象的复制/移动构造函数和/或析构函数具有副作用。
也就是说,如果你给复制/移动构造函数带来副作用,那么你的程序有多个有效的执行路径,具体取决于你的编译器是否想要优化。