Sign in to follow this  
Maxamor

Smart Pointer + Pass By ?

Recommended Posts

Hello all. While refactoring some of my code I came across a topic that I am uncertain in. The way that I understand smart pointers to work is this:
boost:shared_ptr<Widget> myWidget = boost:shared_ptr<Widget>(new Widget());
This will give you an object on the stack (myWidget) which points to an object on the heap (new Widget()), correct? With that being said, if you needed to give other classes references to myWidget, you would want to pass myWidget by value. Otherwise, when other functions or classes go out of scope, they'll destroy the heap object pointed to by myWidget. Is this the correct understanding? When you pass myWidget by value, it's not creating a copy of the heap-allocated object too--is it?

Share this post


Link to post
Share on other sites
Your understanding is correct. Copies of a shared_ptr<> refer to the same object i.e.


boost::shared_ptr<int> p(new int(5));
boost::shared_ptr<int> q(p);

// This won't assert
assert(p == q && p.get() == q.get() && *p == *q);



But other smart pointers may have different copy semantics.

It's perfectly ok to pass a shared_ptr<> by reference, but you'll often want to copy it at some point (often in to a member variable of an object).

[source land="cpp"]
class X
{
public:
explicit X(const boost::shared_ptr<int> &pi) : pi_(pi) { }

private:
boost::shared_ptr<int> pi_;
};



Again, the member variable will refer to the same heap allocated object as the shared_ptr given to the constructor as an argument.

Edd

Share this post


Link to post
Share on other sites
Quote:
When you pass myWidget by value, it's not creating a copy of the heap-allocated object too--is it?


It might, it might not. Passing by value means copying the object, but compiler may realize what you're trying to do, and not do it.

but:


typedef boost::shared_ptr<Widget> WidgetPtr;

class Foo
{
Foo( WidgetPtr & w )
: m_widget( w )
, m_alias( w )
{}

WidgetPtr m_widget;
WidgetPtr &m_alias;
}




This passes the w by reference, but when storing it into m_widget, it's copied by value - the smart pointer, not the data it points to.

m_alias however is a big problem, and reason why compiler or static checkers will complain. The object can indeed be destroyed in between. This is why storing references is generally inadvisable, since it cannot be made safe.

But boost smart_ptr's copy semantics are reliable. Unless you do something that is generally bad from C++'s standpoint, there is nothing to worry about.

The only situation is this:

void foo( WidgetPtr p, ???? );

foo( WidgetPtr( new Widget() ), ??? );




There's a warning against in-place construction in boost's documentation, so I won't repeat it.

As pointed above, smart pointer will not copy the data it points to, just itself.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
The only situation is this:
*** Source Snippet Removed ***

There's a warning against in-place construction in boost's documentation, so I won't repeat it.
Oh yes! I've made this mistake before but was able to figure it out. It makes complete sense why it's a bad idea.

I appreciate your responses. Now I'm clear on what I should and shouldn't be doing.

Thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this