[英]Lifetime of primitive/object value when it's returned from a function
class Foo {
private:
int num;
std::string str;
public:
Foo& operator=(const Foo& rhs) {
this->num = rhs.num;
this->str = rhs.str;
return *this;
}
Foo& operator+(const Foo& rhs) {
Foo tmp(this->num + rhs.num, this->str + rhs.str);
return tmp;
}
};
如果我写一个像Foo f3; f3 = f1 + f2;
Foo f3; f3 = f1 + f2;
,运行时错误发生在this->str = rhs.str;
in operator=()被执行。
我认为在operator+()中制作的临时 std::string object( this->str + rhs.str
) 是区域性的,因此在 function 调用完成时将其删除。 但是 int value( this->num + rhs.num
) 传递得很好,没有问题。
为什么会发生这种差异?
您的 operator+ 返回对名为 tmp 的临时 Foo 的引用。 返回后会自动销毁。
您没有显示最小的可编译示例。 但最有可能的是,随后对 f3 的分配失败。
operator+ 的惯用方法是按值返回 Foo。
// Note the missing & in the Foo return value
Foo operator+( const Foo& rhs )
{
Foo result( this->num + rhs.num, this->str + rhs.str );
return result;
}
您已经正确断言tmp
仅对Foo::operator+
是本地的,因此返回的引用无效(悬空引用)。
但是 int value(this->num + rhs.num) 传递得很好,没有问题。
我认为您指的是这样的代码:
int operator+(const Foo& rhs) {
int tmp(this->num + rhs.num);
return tmp;
}
是的,这行得通。 请注意int operator+(const Foo& rhs)
返回value的重要区别。 也就是说,您不会返回对tmp
的引用,而是返回它的副本。
这就是为什么惯用的operator+
会按值而不是按引用返回的原因。 你要:
// V no reference
Foo operator+(const Foo& rhs) { ... }
另请参阅这个关于规范运算符重载的好问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.