当前位置:  开发笔记 > 编程语言 > 正文

聪明的指针:或谁拥有你的宝贝?

如何解决《聪明的指针:或谁拥有你的宝贝?》经验,为你挑选了3个好方法。

C++完全是关于内存所有权
Aka" Ownership Semantics "

一块动态分配的内存的所有者负责释放该内存.所以这个问题真的变成了拥有记忆的人.

在C++中,所有权都是由RAW指针包含在内部的类型记录的,因此在一个好的(IMO)C++程序中,很少见[RARE并非永远]看到RAW指针传递(因为RAW指针没有推断的所有权因此我们不能告诉谁拥有记忆,因此如果没有仔细阅读文件,你无法分辨谁负责所有权).

相反,很少看到RAW指针存储在类中,每个RAW指针都存储在自己的SMART指针包装器中.(注意:如果你没有一个对象,你不应该存储它,因为你不知道什么时候它会超出范围并被销毁.)

所以问题是:

人们遇到什么类型的所有权语义?

使用哪些标准类来实现这些语义?

你认为它们在哪些情况下有用?

让我们为每个答案保留一种语义所有权,这样他们就可以单独上下投票

摘要:

从概念上讲,智能指针很简单,而且简单易用.我已经看过许多尝试过的实现,但总是以某种方式打破它们,这对于随意使用和示例来说并不明显.因此,我建议始终使用经过良好测试的"智能指针",而不是自己动手.std :: auto_ptr或其中一个提升智能指针似乎涵盖了我的所有需求.

的std :: auto_ptr的:

单身人士拥有该物品.
但允许转让所有权.

用法:
======
这允许您定义显示所有权显式转移的接口.

升压:: scoped_ptr的

单身人士拥有该物品.
不允许转让所有权.

用法:
======
用于显示明确的所有权.
对象将被析构函数或显式重置时销毁.

boost :: shared_ptr (std :: tr1 :: shared_ptr )

多个所有权.
这是一个简单的引用计数指针.当引用计数达到零时,对象被销毁.

用法:
======
当对象可以有多个owers,其生命周期无法在编译时确定.

升压::的weak_ptr

与shared_ptr 一起使用.
在指针循环可能发生的情况下.

用法:
======
用于在仅循环维护共享引用计数时停止保留对象的周期.



1> paercebal..:

简单的C++模型

在我看到的大多数模块中,默认情况下,假设接收指针没有接收所有权.实际上,放弃指针所有权的函数/方法都非常罕见,并且在其文档中明确表达了这一事实.

此模型假定用户仅是他/她明确分配的内容的所有者.其他所有内容都会自动处理(在范围退出处或通过RAII).这是一个类似C的模型,扩展的事实是大多数指针都由对象拥有,这些对象将自动或在需要时释放它们(主要是在所述对象破坏时),并且对象的生命持续时间是可预测的(RAII是你的朋友,再次).

在这个模型中,原始指针是自由流通的,并且大多数都没有危险(但如果开发人员足够聪明,他/她将尽可能使用引用).

原始指针

性病:: auto_ptr的

提高:: scoped_ptr的

智能指向C++模型

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

提高:: shared_ptr的

提高:: weak_ptr的

结论

无论我描述的模型,除非异常,接收指针都没有获得它的所有权,知道谁拥有谁仍然是非常重要的.即使对于大量使用引用和/或智能指针的C++代码也是如此.



2> Fabio Cecone..:

对我来说,这三种类型涵盖了我的大部分需求:

shared_ptr - 当计数器达到零时,引用计数,解除分配

weak_ptr- 与上面相同,但它是a的"奴隶" shared_ptr,不能解除分配

auto_ptr - 当创建和释放发生在同一个函数内部时,或者当对象必须被认为只有一个所有者时.当您将一个指针指定给另一个指针时,第二个指针会从第一个指定"窃取"该对象.

我有自己的实现,但它们也可用于Boost.

我仍然通过引用传递对象(const只要有可能),在这种情况下,被调用的方法必须假定对象仅在调用期间处于活动状态.

还有另一种我使用的指针,我称之为hub_ptr.当你拥有一个必须可以从嵌套在其中的对象访问的对象时(通常作为一个虚拟基类).这可以通过传递weak_ptr给他们来解决,但它本身没有shared_ptr.因为它知道这些对象不会比他长寿,所以它会将hub_ptr传递给它们(它只是常规指针的模板包装器).


它基本上是一个设计合同,使事情清楚.当子对象收到hub_ptr时,它知道指向的对象在子进程的生命周期内不会被销毁,并且对它没有所有权.包含和容器对象都同意一套明确的规则.如果使用裸指针,则可以记录规则,但编译器和代码不会强制执行.
请注意,[Boost文档](http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/scoped_ptr.htm)与您对scoped_ptr的描述相矛盾.它声明它是"不可复制的"并且所有权不能转让.
@Alec Thomas,你是对的.我在考虑auto_ptr并写了scoped_ptr.纠正.
不是创建自己的指针类(hub_ptr),为什么不直接将*this传递给这些对象并让它们作为引用存储?既然你甚至承认这些物品会在拥有类的同时被销毁,我也不明白跳过这么多箍的意义.

3> MSN..:

没有共享所有权.如果您这样做,请确保它只包含您无法控制的代码.

这解决了100%的问题,因为它迫使你理解一切如何相互作用.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有