以下是在互联网上找到的朋友功能的示例:
#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”函数创建一个局部变量并将其作为返回值返回给调用者。这不应该是一个局部变量,并在此堆栈上分配?一旦“重复”完成执行,它不应该被销毁吗?这个例子好吗?
感谢。
答案 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)
{
}
输出线是一种副作用,由于副本缺失可能会被忽略。