Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the benefits and risks, if any, of using std::move with std::shared_ptr

I am in the process of learning C++11 features and as part of that I am diving head first into the world of unique_ptr and shared_ptr.

When I started, I wrote some code that used unique_ptr exclusively, and as such when I was passing my variables around I needed to accomplish that with std::move (or so I was made to understand).

I realized after some effort that I really needed shared_ptr instead for what I was doing. A quick find/replace later and my pointers were switched over to shared but I lazily just left the move() calls in.

To my surprise, not only did this compile, but it behaved perfectly well in my program and I got every ounce of functionality I was expecting... particularly, I was able to "move" a shared_ptr from ObjectA to ObjectB, and both objects had access to it and could manipulate it. Fantastic.

This raised the question for me though... is the move() call actually doing anything at all now that I am on shared_ptr? And if so, what, and what are the ramifications of it?

Code Example

shared_ptr<Label> lblLevel(new Label());

//levelTest is shared_ptr<Label> declared in the interface of my class, undefined to this point
levelTest = lblLevel;

//Configure my label with some redacted code

//Pass the label off to a container which stores the shared_ptr in an std::list
//That std::list is iterated through in the render phase, rendering text to screen
this->guiView.AddSubview(move(lblLevel));

At this point, I can make important changes to levelTest like changing the text, and those changes are reflected on screen.

This to me makes it appear as though both levelTest and the shared_ptr in the list are the same pointer, and move() really hasn't done much. This is my amateur interpretation. Looking for insight. Using MinGW on Windows.

like image 290
M. Ryan Avatar asked Jan 11 '23 20:01

M. Ryan


1 Answers

ecatmur's answer explains the why of things behaving as you're seeing in a general sense.

Specifically to your case, levelTest is a copy of lblTest which creates an additional owning reference to the shared resource. You moved from lblTest so levelTest is completely unaffected and its ownership of the resource stays intact.

If you looked at lblTest I'm sure you'd see that it's been set to an empty value. Because you made a copy of the shared_ptr before you moved from it, both of the existing live instances of the pointer (levelTest and the value in guiView) should reference the same underlying pointer (their get method returns the same value) and there should be at least two references (their use_count method should return 2, or more if you made additional copies).

The whole point of shared_ptr is to enable things like you're seeing while still allowing automatic cleanup of resources when all the shared_ptr instances are destructed.

like image 118
Sean Middleditch Avatar answered Jan 27 '23 09:01

Sean Middleditch