EnDelt64
EnDelt64

Reputation: 1360

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;
    }
};

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

Answers (2)

André
André

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

Lukas-T
Lukas-T

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

Related Questions