智能指针,为什么在更改底层对象之前需要检查我是否是唯一用户?
Smart pointer, why need to check if I am the only user before changing the underlying object?
我正在阅读 C++ Primer,发现这些内容有点令人困惑:
The reset
member is often used together with unique
to control changes
to the object shared among several shared_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
上面引用的文字中强调的文字是什么意思?好迷茫。
更新:
再看一遍课文,我发现我可能漏掉了什么。
所以根据上面的代码,我们假设有2
shared_ptr
(一个是这里提到的p
)指向原始动态内存对象比方说A
.然后如果我想修改对象A
,我分配一个新的动态内存,复制值为A
(new string(*p)
),分配给p
,假设B
。所以最终 A
没有被修改,而只是创建了 A
?
的修改版本的副本
为什么不直接做*p += newVal;
?为什么它与答案中提到的 Copy-on-write 有关?我的意思是,不需要额外的复制操作。所有 shared_ptr
最初都指向动态内存对象 A
。只有 1 个对象。
可能提供更多上下文的屏幕截图:
因为您只能修改 shared_ptr
而不能修改它们引用的对象。这是为了防止数据竞争。
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.
对于reset()
成员函数:
void reset() noexcept;
Effects: Equivalent to shared_ptr().swap(*this)
.
更新:根据新知识进行了大量修订。
简答(针对您的问题的标题):您没有。你在读什么 C++ 入门书?不可能是你在那里引用的例子 primer material.
智能指针背后的整个思想是 'just work',一旦您正确理解了它们,这篇文章的作者就在这里搞了一个噱头,这种噱头很少(如果有的话)在实践中使用。
他似乎试图描述某种在软件中实现的 oh-so-slightly-weird copy-on-write 机制,但他显然已经迷惑了 OP,毫无疑问,他的大多数其他读者也这样做了.这一切都有点愚蠢,而且不值得去理解为什么他们会像现在这样呈现它(或者,实际上,它首先应该做什么)。就像我说的,它在入门书(或其他任何地方)中没有位置。
无论如何,std::shared_ptr::unique()
是有缺陷的(它不是线程安全的)并且将是 going away soon。
它可能一开始就不应该存在,不要使用它。
在线程的各种讨论中出现了另一个问题,那就是改变由 shared_ptr
管理的 object 是否安全。那么你从哪里得到它不是的概念? 当然的是。如果你不能,很多程序根本就写不出来。只是不要同时从两个不同的线程改变相同的 object(这就是标准所称的 数据竞争 )——这是唯一的问题。如果您确实想这样做,请使用互斥锁。
我认为本书的作者在这里描述了如何使用 shared_ptr 实现 Copy-on-write 范式。正如 "this isn't a requirement of shared_ptr, its simply a design decision".
之前的评论中提到的
我正在阅读 C++ Primer,发现这些内容有点令人困惑:
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
上面引用的文字中强调的文字是什么意思?好迷茫。
更新:
再看一遍课文,我发现我可能漏掉了什么。
所以根据上面的代码,我们假设有2
shared_ptr
(一个是这里提到的p
)指向原始动态内存对象比方说A
.然后如果我想修改对象A
,我分配一个新的动态内存,复制值为A
(new string(*p)
),分配给p
,假设B
。所以最终 A
没有被修改,而只是创建了 A
?
为什么不直接做*p += newVal;
?为什么它与答案中提到的 Copy-on-write 有关?我的意思是,不需要额外的复制操作。所有 shared_ptr
最初都指向动态内存对象 A
。只有 1 个对象。
可能提供更多上下文的屏幕截图:
因为您只能修改 shared_ptr
而不能修改它们引用的对象。这是为了防止数据竞争。
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.
对于reset()
成员函数:
void reset() noexcept;
Effects: Equivalent to
shared_ptr().swap(*this)
.
更新:根据新知识进行了大量修订。
简答(针对您的问题的标题):您没有。你在读什么 C++ 入门书?不可能是你在那里引用的例子 primer material.
智能指针背后的整个思想是 'just work',一旦您正确理解了它们,这篇文章的作者就在这里搞了一个噱头,这种噱头很少(如果有的话)在实践中使用。
他似乎试图描述某种在软件中实现的 oh-so-slightly-weird copy-on-write 机制,但他显然已经迷惑了 OP,毫无疑问,他的大多数其他读者也这样做了.这一切都有点愚蠢,而且不值得去理解为什么他们会像现在这样呈现它(或者,实际上,它首先应该做什么)。就像我说的,它在入门书(或其他任何地方)中没有位置。
无论如何,std::shared_ptr::unique()
是有缺陷的(它不是线程安全的)并且将是 going away soon。
它可能一开始就不应该存在,不要使用它。
在线程的各种讨论中出现了另一个问题,那就是改变由 shared_ptr
管理的 object 是否安全。那么你从哪里得到它不是的概念? 当然的是。如果你不能,很多程序根本就写不出来。只是不要同时从两个不同的线程改变相同的 object(这就是标准所称的 数据竞争 )——这是唯一的问题。如果您确实想这样做,请使用互斥锁。
我认为本书的作者在这里描述了如何使用 shared_ptr 实现 Copy-on-write 范式。正如 "this isn't a requirement of shared_ptr, its simply a design decision".
之前的评论中提到的