Kactung
Kactung

Reputation: 730

Returning a smart pointer and assign it a value doesn't work

I am having some problems modifying the content of a smart pointer returned by a class function. Returning a reference to the pointer would be a solution, but I am concerned of it as a bad practice.

This is my code:

#include <memory>
#include <iostream>

class Foo
{
public:
    Foo() : ptr_(new int(5)) {};
    ~Foo() {};

    std::shared_ptr<int> bar()
    {
        return ptr_;
    }

    void print()
    {
        std::cout << *ptr_ << std::endl;
    }

private:
    std::shared_ptr<int> ptr_;
};

int main()
{
    Foo f;
    f.print();

    // First case
    f.bar() = std::make_shared<int>(23);
    f.print();

    // Second case
    f.bar().reset(new int(23));
    f.print();

    // Third case
    *f.bar() = 23;
    f.print();

    return 0;
}

And this is the output:

5
5
5
23

Why only in the third case ptr_ changes its value?

Upvotes: 2

Views: 1268

Answers (4)

Scott Jones
Scott Jones

Reputation: 2908

Because the first two cases are using the assignment operator on a temp returned by bar(), effectively splitting it off from Foo. In the last case, the dereference allows direct mutation on the shared payload.

Upvotes: 1

zakinster
zakinster

Reputation: 10688

It's because bar() should return a reference to the shared pointer in order to do what you expect :

 std::shared_ptr<int>& bar()

Upvotes: 1

Yochai Timmer
Yochai Timmer

Reputation: 49251

bar() returns a copy of the shared_ptr.
So assigning to that copy doesn't change the original shared_ptr.

To make it work as you expected, you should have returned a reference to the internal pointer:

std::shared_ptr<int>& bar()
{
   return ptr_;
}

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409206

Because in the first two cases you only change the returned copy. In the third case you change what the pointer actually points to.

If you want the first two cases to work, return a reference instead.

Upvotes: 1

Related Questions