为了账号安全,请及时绑定邮箱和手机立即绑定

智能指针:谁拥有对象?

智能指针:谁拥有对象?

C++
拉风的咖菲猫 2019-10-14 10:27:36
C ++全部关于内存所有权(也称为所有权语义)。动态分配的内存块的所有者负责释放该内存。因此,问题实际上变成了谁拥有记忆。在C ++所有权中,原始指针被包装在其中,因此在一个良好的(IMO)C ++程序中,很少会看到原始指针传递(罕见,不是从来没有)(因为原始指针没有推断出的所有权,因此我们可以不知道谁是内存的所有者,因此,如果不仔细阅读文档,就无法知道谁对内存负责。相反,很少看到原始指针存储在类中,每个原始指针都存储在其自己的智能指针包装器中。(注意:如果您不拥有某个对象,则不应存储该对象,因为您不知道该对象何时会超出范围并被破坏。)所以问题是:人们遇到过哪种所有权语义?哪些标准类用于实现这些语义?您觉得它们在什么情况下有用?让我们为每个答案保留一种类型的语义所有权,以便可以分别对它们进行表决。摘要:从概念上讲,智能指针很简单,简单的实现也很容易。我已经看到了许多尝试的实现,但是它们总是以某种偶然使用和示例不明显的方式被破坏。因此,我建议始终使用库中经过良好测试的智能指针,而不要自己动手。std::auto_ptr或Boost智能指针之一似乎可以满足我的所有需求。std::auto_ptr<T>:一个人拥有该对象。允许转让所有权。用法:这允许您定义显示所有权显式转移的接口。boost::scoped_ptr<T>一个人拥有该对象。不允许转让所有权。用法:用于显示明确的所有权。对象将由析构函数或明确重置后销毁。boost::shared_ptr<T>(std::tr1::shared_ptr<T>)多重所有权。这是一个简单的引用计数指针。当引用计数达到零时,对象将被销毁。用法:一个对象可以具有多个编译器,且其生存期在编译时无法确定。boost::weak_ptr<T>:用于shared_ptr<T>可能发生指针循环的情况。用法:仅当循环维护共享引用计数时,用于停止保留对象的循环。
查看完整描述

3 回答

?
慕仙森

TA贡献1827条经验 获得超8个赞

对我来说,这三种可以满足我的大部分需求:

shared_ptr -参考计数,计数器达到零时释放

weak_ptr-与上述相同,但它是的“从属” shared_ptr,无法取消分配

auto_ptr-当创建和释放发生在同一个函数中时,或者当对象必须被视为只有一个所有者时。当您将一个指针分配给另一个指针时,第二个指针会从第一个“窃取”对象。

我有自己的实现,但也可以在中找到它们Boost

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

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


查看完整回答
反对 回复 2019-10-14
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

简单的C ++模型

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

该模型假定用户仅是他/她明确分配的所有者。其他所有内容都会自动清除(在示波器出口或通过RAII)。这是一个类似C的模型,扩展了以下事实:大多数指针归对象所有,这些对象将自动或在需要时(通常在销毁对象时)释放它们,并且对象的生存期是可预测的(RAII是您的朋友,再次)。

在此模型中,原始指针可以自由循环并且几乎没有危险(但是,如果开发人员足够聪明,他/她将尽可能使用引用代替)。

  • 原始指针

  • std :: auto_ptr

  • boost :: scoped_ptr

智能指针C ++模型

在充满智能指针的代码中,用户可以希望忽略对象的生存期。所有者永远不是用户代码:它是智能指针本身(再次是RAII)。问题在于,将循环引用与引用计数的智能指针混合使用可能是致命的,因此您必须同时处理共享指针和弱指针。因此,您仍然需要考虑所有权(弱指针可能毫无意义,即使它比原始指针的优势在于它可以告诉您)。

  • boost :: shared_ptr

  • 提升:: weak_ptr

结论

无论我描述的模型是什么,除非有例外否则接收指针都不会获得其所有权知道谁拥有谁仍然非常重要。即使对于C ++代码,也大量使用引用和/或智能指针。


查看完整回答
反对 回复 2019-10-14
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

从boost开始,还有指针容器库。如果仅在对象的上下文中使用对象,则这些对象比标准的智能指针容器要有效且易于使用。


在Windows上,有COM指针(IUnknown,IDispatch和Friends),以及用于处理它们的各种智能指针(例如ATL的CComPtr和Visual Studio中基于_com_ptr类由“ import”语句自动生成的智能指针)。)。


查看完整回答
反对 回复 2019-10-14
  • 3 回答
  • 0 关注
  • 425 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号