Reputation: 730
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
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
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
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
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