c++ - 智能指针 : who owns the object?

标签 c++ memory-management smart-pointers ownership-semantics

很难说出这里问的是什么。这个问题是模棱两可的、含糊的、不完整的、过于宽泛或修辞的,不能以其目前的形式得到合理的回答。如需帮助澄清此问题以便可以重新打开,visit the help center .




9年前关闭。




C++ 是关于内存所有权的 - 又名 所有权语义 .
动态分配的内存块的所有者有责任释放该内存。所以问题真的变成了谁拥有内存。
在 C++ 中,所有权由原始指针包裹在里面的类型记录,因此在一个好的 (IMO) C++ 程序中,看到传递的原始指针是非常罕见的(很少,不是从来没有)(因为原始指针没有推断的所有权,因此我们可以不知道谁拥有内存,因此如果不仔细阅读文档,您就无法判断谁对所有权负责)。
相反,很少看到原始指针存储在类中,每个原始指针都存储在其自己的智能指针包装器中。 ( 注意: 如果你不拥有一个对象,你不应该存储它,因为你不知道它什么时候会超出范围并被销毁。)
所以问题是:

  • 人们遇到过什么类型的所有权语义?
  • 哪些标准类用于实现这些语义?
  • 在什么情况下你觉得它们有用?

  • 让我们为每个答案保留 1 种语义所有权,以便可以单独投票赞成和反对。
    概括:
    从概念上讲,智能指针很简单,简单的实现也很容易。我见过许多尝试过的实现,但它们总是以某种对于随意使用和示例来说并不明显的方式被破坏。因此,我建议始终使用库中经过良好测试的智能指针,而不是使用自己的智能指针。 std::auto_ptr或者 Boost 智能指针之一似乎可以满足我的所有需求。std::auto_ptr<T> :
    单例拥有该对象。允许转让所有权。
    用法:这允许您定义显示所有权显式转移的接口(interface)。boost::scoped_ptr<T>单例拥有该对象。不允许转让所有权。
    用法:用于显示明确的所有权。对象将被析构函数或显式重置时销毁。boost::shared_ptr<T> ( std::tr1::shared_ptr<T> )
    多重所有权。这是一个简单的引用计数指针。当引用计数达到零时,对象被销毁。
    用法:当一个对象可以有多个 ower 时,其生命周期无法在编译时确定。boost::weak_ptr<T> :
    shared_ptr<T> 一起使用在可能发生指针循环的情况下。
    用法:用于在只有循环维护共享引用计数时停止循环保留对象。

    最佳答案

    简单的 C++ 模型
    在我看到的大多数模块中,默认情况下,假设接收指针是 不是 获得所有权。事实上,放弃指针所有权的函数/方法非常罕见,并且在他们的文档中明确表达了这一事实。
    此模型假设用户仅是他/她明确分配的内容的所有者 .其他所有内容都会自动处理(在范围导出处,或通过 RAII)。这是一个类似 C 的模型,由于大多数指针由对象拥有,这些对象将自动或在需要时(大多数情况下在所述对象销毁时)释放它们,并且对象的生命周期是可预测的(RAII 是您的 friend ,再次)。
    在这个模型中,原始指针是自由循环的,而且大多没有危险(但如果开发人员足够聪明,他/她会尽可能使用引用)。

  • 原始指针
  • std::auto_ptr
  • boost::scoped_ptr

  • 智能尖头 C++ 模型
    在充满智能指针的代码中,用户可以希望忽略对象的生命周期。所有者永远不是用户代码:它是智能指针本身(再次是 RAII)。 问题是循环引用与引用计数智能指针混合可能是致命的 ,所以你必须同时处理共享指针和弱指针。所以你仍然需要考虑所有权(弱指针很可能不指向任何东西,即使它相对于原始指针的优势是它可以告诉你)。
  • boost::shared_ptr
  • boost::weak_ptr

  • 结论
    无论我描述的是哪种型号,除非异常(exception),接收指针不会接收其所有权 知道谁拥有谁仍然很重要 .即使对于大量使用引用和/或智能指针的 C++ 代码。

    关于c++ - 智能指针 : who owns the object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/94227/

    相关文章:

    kernel - 内核如何知道虚拟地址空间中的哪些页面对应于换出的物理页面框架?

    java - 为什么 Runtime.freeMemory() 在构造对象后显示更多的内存?

    c++ - 是否可以使shared_ptr协变?

    c++ - 如何在 C++ 中启用 Rust 所有权范式

    c++ - 关于 "circular reference",我使用了 weak_ptr 但内存泄漏仍然发生

    c++ - 为什么从初始化列表中初始化 vector 时不使用 move 构造(通过隐式构造函数)

    c++ - spirit::qi:组合 parser_factory 失败

    c++ - 与 C++ std::future 的数据竞争。编译器重新排序

    c++ - 阴影卷 - 最后阶段

    javascript - 一旦内存达到 4GB 标记,如何防止 Microsoft Edge 重新加载我的页面?