[英]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.