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.
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));
Okay. Let's see if we can talk about this.
std::shared_ptr<Data> x = std::make_shared<Data>();
std::shared_ptr<Data> y = x;
assert(x.get() == y.get());
If I change something about what x
points to, that would change information about y
as well. Because they point to the same thing.
x->member = 3;
assert(x->member == 3);
assert(y->member == 3);
I can change what x
points to without changing what y
points to.
x = std::make_shared<Data>();
assert(x.get() != y.get());
If I do this, then changes to x
are not reflected to in y
. Because they point to different things.
x->member = 4;
assert(x->member == 4);
assert(y->member != 4);
If I want to make a copy of the contents of x
, and store that in y
, then I need to create a new shared object.
y = std::make_shared<Data>(*x);
At this point, both x
and y
have that member variable set to 4. Because x
had it set, and we created *y
with the contents of *x
.
assert(x->member == 4);
assert(y->member == 4);
But, because x
and y
are pointing to different things in memory, we can change one of them.
assert(x.get() != y.get();
x->member = 3;
assert(x->member == 3);
assert(y->member == 4);
If I was to pass a shared_ptr to a function, then it's just like the first case.
void func(std::shared_ptr<Data> z) {
assert(x.get() == z.get());
}
func(x);
I can also release the contents of a particular shared_ptr by using reset()
. This will cause the value that the shared_ptr is pointing at to become NULL.
x.reset();
assert(x.get() == NULL);
With regards to const correctness, it's a bit weird.
const std::shared_ptr<Data> x;
x.reset(); // Fails because the shared_ptr is const.
x->member = 3; // Succeeds because Data is not const.
std::shared_ptr<const Data> x;
x.reset(); // Succeeds because the shared_ptr is not const.
x->member = 3; // Fails because Data is const.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With