代码之家  ›  专栏  ›  技术社区  ›  Rick Jim DeLaHunt

智能指针,为什么在更改基础对象之前需要检查我是否是唯一的用户?

  •  1
  • Rick Jim DeLaHunt  · 技术社区  · 7 年前

    我在看书 C++底漆 发现这些有点混乱:

    这个 reset 成员通常与 unique 控制变化 到几个人共享的对象 shared_ptr S. 在更改 底层对象,我们检查是否是唯一的用户。如果没有,我们 在进行更改之前制作新副本:

    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 共享的 (一个是 p 这里提到)指向原始动态内存对象 A 是的。如果我想修改对象 一个 ,我分配了一个新的动态内存,其拷贝值为 一个 ( new string(*p) ),分配给 第页 ,假设 B 是的。所以最终 一个 未修改,但仅创建的已修改版本的副本 一个 是吗?

    enter image description here

    为什么不直接做 *p += newVal; 是吗?为什么它与 书面复制 在回答中提到?我是说,不需要额外的复制操作。全部 共享的 最初指向动态内存对象 一个 .只有一个对象。


    可能提供更多内容的屏幕截图: enter image description here

    3 回复  |  直到 7 年前
        1
  •  3
  •   Joseph D.    7 年前

    因为你只能修改 shared_ptr 而不是他们所指的对象。这是为了防止数据竞争。

    util.smartptr.shared/4 :

    为了确定是否存在数据竞赛,成员 功能应访问和修改 只有 这个 shared_­ptr weak_­ptr 对象本身和 它们所指的对象。

    变化 use_­count() 不反映可能引入数据的修改 比赛。

    对于 reset() 成员函数:

    void reset() noexcept;
    

    效果:等同于 shared_­ptr().swap(*this) 是的。

        2
  •  4
  •   wtom    7 年前

    我认为这本书的作者在这里描述了 Copy-on-write 范例可以使用共享的ptr来实现。如前所述,“这不是共享PTR的要求,它只是一个设计决策”。

        3
  •  3
  •   catnip    7 年前

    更新:根据新知识进行了实质性修订。


    简短的回答(问题的标题):你不知道。你读的是什么C++底漆?不可能是你引用底漆材料的例子。

    智能指针背后的全部思想是,一旦你正确理解它们,它们就“工作正常”,而这篇文章的作者在这里做了一个特技,如果真的有这种特技的话,在实践中很少使用。

    他似乎在试图描述某种在软件中实现的、有点奇怪的“随写随写”机制,但他显然欺骗了操作系统,毫无疑问,他的大多数读者都是这么做的。这都有点傻,只是不值得尝试去理解他们为什么要像现在这样呈现它(或者,实际上,一开始就应该做什么)。就像我说的,它在底漆(或者其他地方)中没有位置。

    不管怎样, std::shared_ptr::unique() 有缺陷(不是线程安全的)并且 going away soon 是的。 它可能根本就不存在,不要使用它。

    另一个问题在线程中的各种讨论中出现,那就是对由 shared_ptr 是的。好吧,你从哪里得到的不是这样的想法?的 课程 它是。如果你做不到,很多程序根本就写不出来。只是不要同时从两个不同的线程中改变同一个对象(这就是标准所说的 数据竞争 )-这是唯一的问题。如果您确实想这样做,请使用互斥锁。