首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针、智能指针还是共享指针?

指针、智能指针还是共享指针?
EN

Stack Overflow用户
提问于 2009-01-06 17:42:25
回答 5查看 119.8K关注 0票数 126

我使用普通指针编程,但我听说过像Boost这样实现智能指针的库。我还看到在Ogre3D渲染引擎中,对共享指针的深度使用。

这三者之间到底有什么区别,我应该坚持只使用其中的一种类型吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-01-06 18:29:15

Sydius很好地概述了这些类型:

  • Normal指针就是这样--它们指向内存中的某个地方。谁拥有它?只有评论会让你知道。是谁释放了它?希望某些point.
  • Smart指针的所有者是一个涵盖许多类型的通用术语;我假设您指的是使用RAII模式的作用域指针。它是一个堆栈分配的对象,包装了一个指针;当它超出作用域时,它会对它包装的指针调用delete。它“拥有”所包含的指针,因为它负责在某个时刻删除它。它们允许您获取它们包装的指针的原始引用,以便传递给其他方法,以及释放指针,允许其他人拥有它。复制它们不会使sense.
  • Shared指针是一个堆栈分配的对象,它包装了一个指针,因此您不必知道谁拥有它。当内存中对象的最后一个共享指针被析构时,包装的指针也将被删除。

那你什么时候应该使用它们呢?您将大量使用作用域指针或共享指针。你的应用程序中有多少线程在运行?如果答案是“可能很多”,那么如果到处使用共享指针,可能会成为性能瓶颈。原因是创建/复制/销毁共享指针需要是一个原子操作,如果有许多线程在运行,这可能会影响性能。然而,情况并不总是这样--只有测试才能确定。

有一个论点(我喜欢)反对共享指针-通过使用它们,你允许程序员忽略谁拥有一个指针。这可能会导致循环引用的棘手情况(Java可以检测到这些情况,但共享指针检测不到),或者大型代码库中的一般程序员懒惰。

使用作用域指针有两个原因。第一个是为了简单的异常安全和清理操作-如果你想保证一个对象在面对异常时无论发生什么都会被清理,并且你不想堆栈分配这个对象,把它放在一个作用域指针中。如果操作成功,您可以随意将其转移到共享指针,但同时使用作用域指针节省开销。

另一种情况是当你想要清晰的对象所有权时。有些团队喜欢这样,有些则不喜欢。例如,数据结构可以返回指向内部对象的指针。在作用域指针下,它将返回一个应该被视为弱引用的原始指针或引用-在拥有它的数据结构被析构之后访问该指针是错误的,删除它是错误的。在共享指针下,拥有它的对象不能销毁它返回的内部数据,如果有人仍然持有它的句柄-这可能会使资源开放的时间比必要的长得多,或者更糟,这取决于代码。

票数 153
EN

Stack Overflow用户

发布于 2009-01-06 18:21:32

术语“智能指针”包括共享指针、自动指针、锁定指针等。你的意思是说自动指针(更模糊地称为“拥有指针”),而不是智能指针。

哑指针(T*)从来都不是最好的解决方案。它们让您执行显式内存管理,这是冗长的、容易出错的,有时几乎是不可能的。但更重要的是,它们并不代表你的意图。

自动指针删除销毁时的指针对象。对于数组,首选封装,如vector和deque。对于其他对象,很少需要将它们存储在堆上-只需使用局部变量和对象组合即可。不过,对于返回堆指针的函数--例如工厂和多态返回--也会出现对自动指针的需求。

当指向被指针对象的最后一个共享指针被销毁时,共享指针将删除该被指针对象。当您想要一个简单的、开放式的存储方案时,这是很有用的,其中预期的生命周期和所有权可能会根据情况而变化很大。由于需要保持一个(原子)计数器,它们比自动指针慢一点。有些人半开玩笑地说,共享指针是为那些不会设计系统的人准备的--请自己判断。

对于共享指针的必要副本,也可以查找弱指针。

票数 34
EN

Stack Overflow用户

发布于 2009-01-06 17:46:01

智能指针会在超出作用域后自行清理(从而消除对大多数内存泄漏的恐惧)。共享指针是一种智能指针,它会对存在的指针实例数进行计数,并且仅在计数达到零时才清理内存。通常,只使用共享指针(但请确保使用正确的类型--数组有不同的类型)。他们和RAII有很多关系。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/417481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档