问题
I am reading C++ Primer and find these kinda confusing:
The
reset
member is often used together withunique
to control changes to the object shared among severalshared_ptr
s. 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
?
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:
回答1:
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
andweak_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)
.
回答2:
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".
回答3:
Update: Substantially revised, based on new knowledge.
Short answer (to the title of your question): you don't. What C++ primer are you reading? No way is the example you quote there primer material.
The whole idea behind smart pointers is that they 'just work', once you understand them properly, and the author of the passage has pulled a stunt here which would rarely, if ever, be used in practice.
He appears to be trying to describe some sort of oh-so-slightly-weird copy-on-write mechanism implemented in software, but he has clearly bamboozled the OP and no doubt most of the rest of his readership in doing so. It's all a bit silly and it's just not worth trying to understand why they present it as they do (or, indeed, just what it is supposed to do in the first place). Like I say, it has no place in a primer (or probably anywhere else).
Anyway, std::shared_ptr::unique()
is flawed (it is not threadsafe) and will be going away soon.
It should probably never have existed in the first place, don't use it.
One other issue arose during various discussions in the thread, and that is whether it is safe to mutate an object managed by a shared_ptr
. Well wherever did you get the notion that it isn't? Of course it is. If you couldn't, many programs simply could not be written at all. Just don't mutate the same object from two different threads at the same time (that's what the standard calls a data race) - that's the only issue. If you do want to do that, use a mutex.
来源:https://stackoverflow.com/questions/51276822/smart-pointer-why-need-to-check-if-i-am-the-only-user-before-changing-the-under