智能指针:或谁拥有你的宝贝?
C ++全是关于内存所有权的
又名“ 所有权语义 ”
一块动态分配的内存的所有者负责释放该内存。 所以这个问题真的变成谁拥有记忆。
在C ++中,所有权由一个RAW指针包装在内部的类型记录,因此在一个好的(IMO)C ++程序中,很少见到RAW RAW指针传递过来(因为RAW指针没有推断的所有权,所以我们不能告诉谁拥有记忆,因此如果没有仔细阅读文件,你不能分辨谁对所有权负责)。
相反,很少见到存储在类中的RAW指针,每个RAW指针都存储在它自己的SMART指针包装器中。 (注意:如果你不拥有一个对象,你不应该存储它,因为你不知道它何时会超出范围并被销毁。)
所以问题是:
让我们为每个答案保留一种语义所有权,以便他们可以单独进行投票
概要:
概念智能指针很简单,而且天真的实现很容易。 我见过很多尝试的实现,但总是以某种方式破坏了它,这对于偶然使用和示例并不明显。 因此,我建议您始终使用库中经过良好测试的“智能指针”,而不是滚动自己的。 std :: auto_ptr或其中一个boost智能指针似乎涵盖了我所有的需求。
的std :: auto_ptr的<T>:
一个人拥有这个物体。
但允许转让所有权。
用法:
======
这使您可以定义显示所有权显式转移的接口。
升压:: scoped_ptr的<T>
一个人拥有这个物体。
不允许转让所有权。
用法:
======
用于显示明确的所有权。
对象将被析构函数销毁或者在显式重置时销毁。
boost :: shared_ptr <T>(std :: tr1 :: shared_ptr <T>)
多重所有权。
这是一个简单的引用计数指针。 当引用计数达到零时,对象被销毁。
用法:
======
当对象可以拥有多个在编译时无法确定生命周期的owers时。
升压::的weak_ptr <T>
与shared_ptr <T>一起使用。
在可能发生指针循环的情况下。
用法:
======
当只有循环维持一个共享的refcount时,用于停止保留对象的循环。
对我来说,这三种类型涵盖了我的大部分需求:
shared_ptr
- 引用计数,当计数器达到零时解除分配
weak_ptr
- 与上面相同,但是它是shared_ptr
的“奴隶”,不能释放
auto_ptr
- 当创建和取消分配发生在同一个函数内部时,或者当对象必须被视为一个所有者时。 当您将一个指针指定给另一个指针时,第二个从第一个'抢夺'对象。
我有我自己的这些实现,但它们也可以在Boost
。
我仍然通过引用传递对象( const
只要有可能),在这种情况下,被调用的方法必须假定该对象仅在调用期间处于活动状态。
还有一种我使用的指针,我称之为hub_ptr 。 这是当你有一个对象必须可以嵌入它的对象(通常作为一个虚拟的基类)。 这可以通过将weak_ptr
传递给它们来解决,但是它本身没有shared_ptr
。 因为它知道这些对象的寿命不会超过他,所以它将一个hub_ptr传递给它们(它只是一个模板封装到一个常规指针)。
简单的C ++模型
在我看到的大多数模块中,默认情况下,假设接收指针未获得所有权。 事实上,放弃指针所有权的函数/方法都非常罕见,并且在其文档中明确地表达了这一事实。
该模型假设用户只是他/她明确分配的所有者 。 其他一切都会自动处理(在范围退出或通过RAII)。 这是一个类似C的模型,由于大多数指针由拥有对象所拥有的事实所扩展,这些对象将自动或在需要时释放它们(主要是在所述对象被破坏的情况下),并且对象的生存期是可预测的(RAII是你的朋友,再次)。
在这个模型中,原始指针是自由流通的,而且大多不是危险的(但是如果开发人员足够聪明,他/她将尽可能使用引用)。
智能指向C ++模型
在充满智能指针的代码中,用户可能希望忽略对象的生命周期。 所有者永远不会是用户代码:它是智能指针本身(又是RAII)。 问题是循环引用与引用计数智能指针混合在一起可能是致命的 ,因此您必须同时处理共享指针和弱指针。 所以你仍然有所有权考虑(弱指针可能指向没有,即使它比原始指针的优势是它可以告诉你这样做)。
结论
无论我描述的模型是什么, 除非例外,接收指针都没有收到它的所有权 , 知道谁拥有谁是非常重要的 。 即使对于大量使用引用和/或智能指针的C ++代码。
没有共享所有权。 如果你这样做,确保只有你不能控制的代码。
这解决了100%的问题,因为它会迫使你理解每件事物如何相互作用。
链接地址: http://www.djcxy.com/p/20767.html