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

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-14 03:37:09

问题


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?

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




回答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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!