Search code examples
c++boostshared-ptr

Copy boost::shared_ptr


typedef boost::shared_ptr<SomeData> data_ptr;
data_ptr cached_ptr;   // class member 
bool someWork(data_ptr& passed_ptr)
{
  // must copy passed_ptr = cached_ptr under some conditions
  // without pointing at the same memory 
  // I saw somewhere that I should do 
  // passed_ptr.reset(new SomeData(???))
  // I don't have a "reset" on passed_ptr
}

I looked at documentation;

copy and converting constructors

shared_ptr(shared_ptr const & r); // never throws
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
Requires: Y* should be convertible to T*.

Effects: If r is empty, constructs an empty shared_ptr; otherwise,
         constructs a shared_ptr that shares ownership with r.

I don't know how that works - is it like this ?

passed_ptr = shared_ptr(cached_ptr);

? Where would the const go ? And what does it mean that they share ownership ? Then it is not a copy, if I modify "passed_ptr", the change will affect "cached_ptr" ?

I can't find examples... Please help.

Thank you.


Solution

  • Well, if you have a shared_ptr and you assign it to another shared_ptr, those two shared pointers will share ownership of the object - meaning the reference counting for the pointed object 's ownership will be increased by one.

    In fact, in the above line, you do not need to construct a temporary shared pointer at all. This is enough:

    passed_ptr = cached_ptr;
    

    Anyway, copy-constructing a shared_ptr basically follows the same logic: you start with a shared pointer, and you end up with two shared pointers that co-own the same object (meaning that the object will be destroyed only when both of those shared pointers get destroyed). So when you do this:

    passed_ptr = shared_ptr(cached_ptr);
    

    You actually start with one shared pointer (cached_ptr) to a given object, then create a temporary one (that brings the reference count to 2) which gets in turn assigned to passed_ptr (bringing the reference count to 3), and eventually gets destroyed (bringing the reference count back to 2).

    On the other hand, if what you want is to have passed_ptr as a shared pointer to a copy of the object being pointed to by cached_ptr, then you should rather do (supposing Data is copyable, of course):

    passed_ptr = boost::make_shared<Data>(*cached_ptr);
    

    Or, alternatively:

    passed_ptr.reset(new Data(*cached_ptr));