4

在下面的代码中,它打印出两个不同的内存位置。这对我来说很有意义,因为我是按价值返回的。

#include <iostream>

using namespace std;

class Foo {
public:
        Foo () {}
//      Foo (const Foo &) { cout << "Copy con" << endl; }
};

Foo test () {
        Foo foo;
        cout << &foo << endl;
        return foo;
}

int main () {
        Foo foo = test();
        cout << &foo << endl;
}

但是,如果我在上面的代码中取消注释复制构造函数并再次运行它,它会输出相同的内存位置两次。为什么?它根本不会打印出“Copy con”,所以我知道复制构造函数没有被调用。似乎复制构造函数的存在会导致某种优化,即使它没有被调用。

我在 GCC 4.6.3 上使用“g++ -Wall test.cpp -o test”进行编译。

4

1 回答 1

2

这是返回值优化的结果。基本上,您的编译器忽略了 return 语句导致的昂贵的复制操作,即使复制构造函数有副作用。

这背后的原因是返回一个复杂的对象是昂贵的。编译器不是在复制上浪费时间,而是在调用者的堆栈帧中秘密地创建一个隐藏对象,并将对该隐藏对象的引用传递给被调用函数,并将函数的返回值直接复制到该隐藏对象中。

C++ 标准明确说明了这一点(ISO-IEC 14882:2011 12.8 第 31 段):

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数具有副作用。

于 2012-09-12T11:11:58.533 回答