表明这是按照以下方式完成的
class X {
X& operator+=(const X& rhs)
{
// actual addition of rhs to *this
return *this;
}
};
inline X operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
我理解为什么参数lhs
需要通过值来获取,但为什么我们需要按值返回它?我的意思是,以下问题是什么:
inline X& operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
在函数内部,lhs
是一个新的X
,修改它不会影响两个操作数中的任何一个。由于这是新的,我们可以通过引用返回它,对吗?
答案 0 :(得分:3)
返回对本地对象的引用的问题是调用者将收到到达时已经死亡的内容。
当你退出一个函数时,所有本地都被销毁,所以你不能继续使用对它们的引用。
代码
const X& res = a+b;
如果操作符按值返回,将起作用,因为语言中有一条特定的规则,即绑定到引用的临时对象将保持活动状态,直到引用本身被销毁。
返回引用是不同的,因为对象的生命周期是被调用者的责任,而不是调用者的责任。因此,最终结果将是一个绑定到已经被销毁的对象的引用。
即使只是
X res;
res = a+b;
不起作用,因为当操作员调用返回时,对象在分配到res
之前被销毁。对于复制构造函数X res = a+b;
也是如此。
答案 1 :(得分:0)
从不返回ba引用,如果退出函数后您引用的值将不再存在。
在这种情况下,lhs
将存在,直到函数返回。如果通过引用返回,则该引用将“指向”不再存在的值,并且任何使用它的尝试都将导致未定义的行为。
这就是按价值返回的原因。但不用担心,许多编译器可以优化附加副本,实际上它不是复制而是移动操作,所以即使它没有被优化掉,“重”对象也会被移动而不会被复制,因为C ++ 11。 / p>
答案 2 :(得分:0)
不是严格地回答这个问题,而是为了帮助理解参考文献...在返回引用时要非常谨慎,除非你知道指示对象(被引用的对象)是稳定的。
这样做是不安全的
std::string baa = "sheep";
std::cout << doNothing(baa) << std::endl; // works
std::cout << doNothing("goat") << std::endl; // UNSAFE
您将在下面显示的第二个电话中失败
string("goat")
这是因为第二次调用涉及隐式创建临时对象(使用构造函数调用name()
的std :: string类型)
相比之下,从class Person
{
private: std::string _name;
public: const std::string& name() { return _name; }
// other constructors and ways to set a _name
};
_name
可以合理地确保类对象(以及它的内部#include <iostream.h>
#include <conio.h>
void strr(char name[]);
void main(){
char name1[10];
cout << "Enter name";
cin >> name1;
strr(name1);
getch();
}
void strr(char name[]){
cout << name;
}
)将保持足够长的时间以使引用对调用者有用。