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

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?

enter image description here

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: enter image description here

3 answers

  • answered 2018-07-11 03:47 codekaizer

    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).

  • answered 2018-07-11 04:12 Paul Sanders

    Update: I thought about this some more, educated myself a little, and decided this post is a little harsh. I will amend it soon.

    It's still a terrible example though. Why are they talking about copy-on-write trickery like this in a primer?


    What C++ primer are you reading? That is a terrible piece of advice - no professional programmer would ever write code like that.

    The whole idea behind smart pointers is that they 'just work', once you understand them properly, and the author of the passage you quote clearly does not. To put it another way, if you have to start pulling stunts like this then there is something wrong (very wrong) with the design of your code.

    std::shared_ptr::unique() should never have been brought into this world in the first place - it just gives the inexperienced a rope to hang themselves with. It is going away soon, don't use it.

  • answered 2018-07-11 08:06 wtom

    I think authors of the book described here how Copy-on-write paradigm can be implemented using shared_ptr. As mentioned in comments before "this isn't a requirement of shared_ptr, its simply a design decision".