智能指针:谁拥有对象?

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>可能发生指针循环的情况。


用法:仅当循环维护共享引用计数时,用于停止保留对象的循环。


拉风的咖菲猫
浏览 426回答 3
3回答

慕仙森

对我来说,这三种可以满足我的大部分需求:shared_ptr&nbsp;-参考计数,计数器达到零时释放weak_ptr-与上述相同,但它是的“从属”&nbsp;shared_ptr,无法取消分配auto_ptr-当创建和释放发生在同一个函数中时,或者当对象必须被视为只有一个所有者时。当您将一个指针分配给另一个指针时,第二个指针会从第一个“窃取”对象。我有自己的实现,但也可以在中找到它们Boost。我仍然通过引用传递对象(const在可能的情况下),在这种情况下,被调用方法必须假定对象仅在调用期间处于活动状态。我使用的另一种指针称为hub_ptr。这是当您有一个必须从嵌套在其中的对象(通常作为虚拟基类)访问的对象时。可以通过将a传递weak_ptr给他们来解决,但本身没有a&nbsp;shared_ptr。众所周知,这些对象的寿命不会比他长,因此将hub_ptr传递给它们(它只是常规指针的模板包装器)。

蝴蝶刀刀

简单的C ++模型在大多数模块中,默认情况下,我看到的是假定接收指针未获得所有权。实际上,放弃指针所有权的函数/方法非常罕见,并且在其文档中明确表达了这一事实。该模型假定用户仅是他/她明确分配的所有者。其他所有内容都会自动清除(在示波器出口或通过RAII)。这是一个类似C的模型,扩展了以下事实:大多数指针归对象所有,这些对象将自动或在需要时(通常在销毁对象时)释放它们,并且对象的生存期是可预测的(RAII是您的朋友,再次)。在此模型中,原始指针可以自由循环并且几乎没有危险(但是,如果开发人员足够聪明,他/她将尽可能使用引用代替)。原始指针std :: auto_ptrboost :: scoped_ptr智能指针C ++模型在充满智能指针的代码中,用户可以希望忽略对象的生存期。所有者永远不是用户代码:它是智能指针本身(再次是RAII)。问题在于,将循环引用与引用计数的智能指针混合使用可能是致命的,因此您必须同时处理共享指针和弱指针。因此,您仍然需要考虑所有权(弱指针可能毫无意义,即使它比原始指针的优势在于它可以告诉您)。boost :: shared_ptr提升:: weak_ptr结论无论我描述的模型是什么,除非有例外,否则接收指针都不会获得其所有权,知道谁拥有谁仍然非常重要。即使对于C ++代码,也大量使用引用和/或智能指针。

蓝山帝景

从boost开始,还有指针容器库。如果仅在对象的上下文中使用对象,则这些对象比标准的智能指针容器要有效且易于使用。在Windows上,有COM指针(IUnknown,IDispatch和Friends),以及用于处理它们的各种智能指针(例如ATL的CComPtr和Visual Studio中基于_com_ptr类由“ import”语句自动生成的智能指针)。)。
打开App,查看更多内容
随时随地看视频慕课网APP