局部变量(堆栈)作为函数返回值返回

时间:2017-11-23 07:40:32

标签: c++

以下是在互联网上找到的朋友功能的示例:

#include <iostream>
using namespace std;

class Rectangle {
    int width, height;
  public:
    Rectangle() {}
    Rectangle(const Rectangle &r) { 
        width = r.width; 
        height = r.height;
        cout << "copy\n";
    }
    Rectangle (int x, int y) : width(x), height(y) {}
    int area() {return width * height;}
    friend Rectangle duplicate (const Rectangle&);
};

Rectangle duplicate (const Rectangle& param)
{
  Rectangle res;
  res.width = param.width*2;
  res.height = param.height*2;
  return res;
}

int main () {
  Rectangle foo;
  Rectangle bar (2,3);
  foo = duplicate (bar);
  cout << foo.area() << '\n';
  return 0;
}

输出:

24

请注意,朋友“duplicate”函数创建一个局部变量并将其作为返回值返回给调用者。这不应该是一个局部变量,并在此堆栈上分配?一旦“重复”完成执行,它不应该被销毁吗?这个例子好吗?

感谢。

2 个答案:

答案 0 :(得分:10)

想想常规类型:

int getInt(void) {
    int a = 5:
    return a;
}

该函数并不真正返回局部变量a。相反,它会返回a的副本。同样,函数不返回res,而是复制它。

实际上,编译器可能会通过避免复制Rectangle来检测您的功能并优化功能。

要观察构造函数调用,请使用

进行编译
g++ -fno-elide-constructors foo.cpp -o foo

您必须disable return value optimization for g++-fno-elide-constructors),这是一项非常基本的优化,即使使用-O0也会启用。

答案 1 :(得分:3)

你的函数按值返回Rectangle,所以应该没问题。

Rectangle duplicate (const Rectangle& param)

返回的对象不在同一个存储中,与本地变量从语言的抽象级别声明的对象不同。事实上,正如Justin所说,编译器可以优化时间对象的创建。

如果你声明

,你会变成红色
Rectangle& duplicate (const Rectangle& param)

然后函数会尝试返回对局部变量的引用。

如何编写代码,它等同于表达式。

return Rectangle(param.width*2, param.height*2);

复制构造函数:

Rectangle(const Rectangle &r) { 
    width = r.width; 
    height = r.height;
}

应该正确写成

Rectangle(const Rectangle &r): width(r.width), height(r.height) 
{ 
}

输出线是一种副作用,由于副本缺失可能会被忽略。