智能指针的优点和缺点

时间:2009-12-15 07:41:26

标签: c++ smart-pointers

我开始知道智能指针用于资源管理并支持RAII。

但是智能指针看起来不聪明并且使用它时需要注意的事项是什么?

10 个答案:

答案 0 :(得分:19)

智能指针无法帮助对付类似图形的结构中的循环。

例如,对象A持有一个指向对象B和对象B的智能指针 - 返回到对象A.如果在断开A与B(或B与A断开)之前释放所有指向A和B的指针,则A和B都将相互拥抱,形成幸福的记忆泄漏。

垃圾收集可以帮助解决这个问题 - 它可以看到两个对象都无法访问并释放它们。

答案 1 :(得分:10)

我想提一下性能限制。智能指针通常使用原子操作(例如Win32 API中的InterlockedIncrement )进行引用计数。这些函数明显慢于普通整数运算。

在大多数情况下,这种性能损失不是问题,只要确保你没有制作太多不必要的智能指针对象副本(更喜欢在函数调用中通过引用传递智能指针)。

答案 2 :(得分:6)

这非常有趣:Smart Pointers
这是Andrei Alexandrescu的“现代C ++设计”中的一个示例章节。

答案 3 :(得分:5)

注意过渡 - 在原始指针和智能指针之间进行分配时。糟糕的智能指针 - 如_com_ptr_t - 通过允许隐式转换使情况变得更糟。大多数错误都发生在过渡时期。

注意周期 - 如上所述,你需要弱指针来打破周期。但是,在复杂的图表中并不总是那么容易。

选择太多 - 大多数库提供不同的实现,具有不同的优点/缺点。不幸的是,大多数时候这些不同的变体是不兼容的,这在混合库时变成了探测器。 (比如,LibA使用LOKI,LibB使用boost)。必须提前计划enable_shared_from_this糟透了,不得不在intrusive_ptrshared_ptrweak_ptr之间为一堆对象决定命名约定。


对我而言,shared_ptr(或类似功能之一)的最大优势在于它在创建时与其销毁策略相关联。 C ++和Win32都提供了很多方法来摆脱它甚至不好笑的东西。在构造时耦合(不影响指针的实际类型)意味着我在一个地方都有两个策略。

答案 4 :(得分:3)

除了技术限制(已经提到:循环依赖)之外,我要说智能指针最重要的是要记住它仍然是一种解决方法,可以删除堆分配对象。 对于大多数情况,堆栈分配是最佳选择 - 以及使用引用 - 来管理对象的生命周期。

答案 5 :(得分:1)

以下是一些事情

  • 没有明确的实体可以摧毁这个物体。通常希望确切地知道对象何时以及如何被销毁
  • 循环依赖 - 如果它们存在,您将有内存泄漏。这通常是weak_ptr来救援的地方。

答案 6 :(得分:0)

以下文章是一篇非常有趣的论文

Smart Pointers: Can't Live With 'Em, Can't Live Without 'Em

答案 7 :(得分:0)

众所周知,雷蒙德对智能指针充满矛盾。关于when the destructor actually runs存在一些问题(请注意,析构函数在明确定义的时间内以明确定义的顺序运行;只是偶尔会忘记之后的 你函数的最后一行。)

还记得“智能指针”是一个非常大的类别。我在该类别中加入std::vectora std::vector is essentially a smart array)。

答案 8 :(得分:0)

在具有周期的某些类型的数据结构中,引用计数存在问题。从多个线程访问智能指针也可能存在问题,对引用计数的并发访问可能会导致问题。在boost中有一个名为atomic.hpp的实用程序可以缓解这个问题。

答案 9 :(得分:0)

当使用与原始指针混合的智能指针(对于相同的对象)时,许多人遇到问题。一个典型的例子是与使用原始指针的API交互时 例如;在boost::shared_ptr中有一个.get()函数返回原始指针。如果小心使用,功能很好,但很多人似乎都会绊倒它 恕我直言,这是一个“漏洞抽象”的例子。