Smart pointer, why need to check if I am the only user before changing the underlying object?

  • A+
Category:Languages

I am reading C++ Primer and find these kinda confusing:

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 string(*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 

What does the emphasized text mean in the quoted text above? So confused.

Update:

After reading the text again, I find out that I may miss something.

So according the code above, let's assume there are 2 shared_ptr (one is p mentioned here) pointing to the original dynamic memory object let's say A. Then if I want to modify object A, I allocate a new dynamic memory with the copy value of A(new string(*p)), assign it to p, let's say B. So eventually A is not modified, but only create a copy of modified version of A?

Smart pointer, why need to check if I am the only user before changing the underlying object?

Why not directly do *p += newVal;? And why is it related to Copy-on-write mentioned in answers? I mean, there's no extra copy operation needed. All shared_ptr originally points to dynamic memory object A. Only 1 object.


Screenshot that may supply a little bit more context: Smart pointer, why need to check if I am the only user before changing the underlying object?

 


For you are only allowed to modify the shared_ptr and not the objects they refer to. This is to prevent data races.

From util.smartptr.shared/4:

For purposes of determining the presence of a data race, member functions shall access and modify only the shared_­ptr and weak_­ptr objects themselves and not objects they refer to.

Changes in use_­count() do not reflect modifications that can introduce data races.

For the reset() member function:

void reset() noexcept; 

Effects: Equivalent to shared_­ptr().swap(*this).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: