我开始知道智能指针用于资源管理并支持RAII。
但是智能指针看起来不聪明并且使用它时需要注意的事项是什么?
答案 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_ptr
,shared_ptr
和weak_ptr
之间为一堆对象决定命名约定。
对我而言,shared_ptr(或类似功能之一)的最大优势在于它在创建时与其销毁策略相关联。 C ++和Win32都提供了很多方法来摆脱它甚至不好笑的东西。在构造时耦合(不影响指针的实际类型)意味着我在一个地方都有两个策略。
答案 4 :(得分:3)
除了技术限制(已经提到:循环依赖)之外,我要说智能指针最重要的是要记住它仍然是一种解决方法,可以删除堆分配对象。 对于大多数情况,堆栈分配是最佳选择 - 以及使用引用 - 来管理对象的生命周期。
答案 5 :(得分:1)
以下是一些事情
weak_ptr
来救援的地方。答案 6 :(得分:0)
以下文章是一篇非常有趣的论文
答案 7 :(得分:0)
还记得“智能指针”是一个非常大的类别。我在该类别中加入std::vector
(a std::vector
is essentially a smart array)。
答案 8 :(得分:0)
在具有周期的某些类型的数据结构中,引用计数存在问题。从多个线程访问智能指针也可能存在问题,对引用计数的并发访问可能会导致问题。在boost中有一个名为atomic.hpp的实用程序可以缓解这个问题。
答案 9 :(得分:0)
当使用与原始指针混合的智能指针(对于相同的对象)时,许多人遇到问题。一个典型的例子是与使用原始指针的API交互时
例如;在boost::shared_ptr
中有一个.get()
函数返回原始指针。如果小心使用,功能很好,但很多人似乎都会绊倒它
恕我直言,这是一个“漏洞抽象”的例子。