First we have a shared_ptr defined as below:
shared_ptr<int> p(new int(42));
According to the text below:
The reset member is often used together with unique to control changes to the object shared among several shared_ptrs. Before changing the underlying object, we check whether we’re the only user. If not, we make a new copy before making the change:
if (!p.unique())
p.reset(new int(*p)); // we aren't alone; allocate a new copy
*p += newVal; // now that we know we're the only pointer, okay to change this object
Question:
Shouldn't we only reset p when there's only 1 copy (p.use_count() == 1).
Here, if i read it correctly we're resetting p when p.use_count() != 1. Seems like opposite.
Thanks for any help.
The various shared_ptr
s scattered throughout the program are all different instances of shared_ptr
that, in this example, potentially point to the same object. If there is only one shared_ptr
referring to the object O
, we can change O
with impunity. Otherwise we want to prevent other holders of shared_ptr
s from being affected by the changes made to O
by one holder.
Trivial example: if there are more than one shared_ptr
instances pointing to O
,
P1
points to O
P2
points to O
we copy O
so that the changes the owner of P1
wishes to make are not seen by the owner of P2
. We will wind up with
P1
points to Copy
P2
points to O
Now that P1
is the only pointer referencing Copy
, P1's holder can make changes without affecting P2
. And since P2
is the only pointer to O
, it can make changes without copying O
in the future, unless P2
is copied into P3
and we once again have multiple "owners" of O
.
You sometimes see behaviour like this with string implementations. When you copy this kind of string, both strings save storage and time by sharing the source string's data. But if either string needs to change that data, it pays for a new copy so that it is the only one changed.