Reputation: 1360
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;
}
};
If I write a code like Foo f3; f3 = f1 + f2;
, runtime error occurs when this->str = rhs.str;
in operator=() is executed.
I think temporary std::string object(this->str + rhs.str
) made in operator+() is regional so it is removed when the function call is finished. But int value(this->num + rhs.num
) is passed well without problems.
Why is this difference happening?
Upvotes: 0
Views: 68
Reputation: 19337
Your operator+ returns a reference to the temporary Foo called tmp. It will be automatically destroyed after the return.
You don't show a minimal, compilable example. But most likely, the assignment afterwards to f3 then fails.
The idiomatic approach for an operator+ is to return Foo by value.
// 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;
}
Upvotes: 1
Reputation: 11340
You already correctly asserted that tmp
is only local to Foo::operator+
and thus the returned reference is invalid (a dangling reference).
But int value(this->num + rhs.num) is passed well without problems.
I think you refer to code like this:
int operator+(const Foo& rhs) {
int tmp(this->num + rhs.num);
return tmp;
}
Yes, that works. Notice the important difference that int operator+(const Foo& rhs)
returns a value. That is, you don't return a reference to tmp
, but a copy of it.
That's why an idiomatic operator+
would return by value instead of by reference. You want:
// V no reference
Foo operator+(const Foo& rhs) { ... }
See also this great question about canonical operator overloading.
Upvotes: 1