智能指针。何时,何地以及如何?

时间:2009-07-13 14:59:32

标签: c++ smart-pointers

首先,由于存在不同类型的智能指针,我想将这个问题集中在其中两个上:引用计入侵入式和非侵入式智能指针。每个指针类型都会单独询问该问题。

我不确定如何制定我的问题,所以这就是我不问的问题: 我不是在问为什么或什么时候需要智能指针。我不应该使用哪种类型的智能指针以及用于什么。

这就是我的要求,我希望它足够清楚:在处理“智能管理”对象时,我应该在哪些上下文中使用哪种指针语义?也就是说,智能指针语义,原始指针语义,其他东西(比如对智能指针的引用)?

很明显,当我“存储”指向对象的指针(对象是引用计数的内存实体)时,例如全局指针,或者作为类成员,它应该是一个智能指针,所以它会声称所有权,但其他情况呢?

当我将指针作为函数参数传递时,它应该是智能指针,原始指针,对智能指针的引用,还是其他什么?返回指针怎么样?本地指针?等......

当然,我可以在任何地方使用智能指针,这是最安全的选择,但我觉得这实际上是不必要的并增加了开销。

7 个答案:

答案 0 :(得分:5)

恕我直言,有时候做事比做一点点性能更好更好。如果你总是使用智能指针,我想你会更快地做事。

我的建议:到处使用智能指针。然后使用分析器查看它是否会产生相当大的开销。它在哪里,改变它:)

答案 1 :(得分:4)

我建议你尽可能地限制智能或其他指针的使用。我不知道你的背景,但很多人来自Java或C#等语言,他们应该真正使用值并通过引用调用。在C ++程序中使用指针应该相对较少。

答案 2 :(得分:2)

如果您想要对比“智能指针语义”和“原始指针语义”,那么您错误地认为可以将所有“智能指针语义”组合在一起。我不同意。 boost::scoped_ptrboost::shared_ptr之间的差异与差异bwteeen boost::shared_ptrT*

具有相同的数量级

当您将指向对象的指针“存储”为类成员时,您并没有真正说过很多关于语义的内容。如果引用的对象在逻辑上是一个成员(“拥有”),那么是的,你需要一个智能指针。但是具有非常特定的语义:单一所有权。这意味着没有共享所有权,也没有弱指针来命名其他两个常见的智能指针。另一方面,如果您存储指向错误记录对象的指针,则可能需要弱指针。这将防止您在关机期间崩溃 - 如果日志消失,弱指针将为NULL。

类似地,当您从函数返回指针时,案例的实际语义将决定您需要的指针类型。不是从函数返回它的简单事实。

答案 3 :(得分:2)

我的指针列表:

  • 正常用法:普通成员和(const)对它们的引用
  • 共享并保持对象存活(所有者,容器):shared_ptr
  • 分享,但没有保持活力(用户):weak_ptr
  • 作用域用法:scoped_ptr
  • 其他用法(输出参数,...):原始指针

答案 4 :(得分:1)

在许多情况下,智能指针的使用与内存管理和/或异常处理有关。即使在复杂的try / catch环境中,STL auto_ptr也能整齐地管理破坏。智能指针可用于将指向对象的生命周期委派给智能指针。只要难以遵循范式“摧毁你创造它的对象”,通常就需要它。当您无法轻松管理共享对象时,引用类型智能指针非常有用。我更喜欢用一个好的架构来解决这类问题,但有时智能指针是最好的方法。

答案 5 :(得分:0)

根据我的经验,当我将对象传递给不需要存储对象引用的函数时(否则,调用函数不会以任何方式影响对象的生命周期),那么通过引用传递对象是安全的。这使代码与智能指针类型“联系”。

另一方面,总是使用智能指针类型是“永远安全”,所以当有疑问时....

答案 6 :(得分:0)

"When I'm passing a pointer as a function argument, should it be a smart-pointer, a raw
pointer, a reference to a smart pointer, or maybe something else? What about returned
pointers? Local pointe rs? so on..."

我的2p,除非你有明显的理由使用shared_ptrs:

不要将指针传递给函数,将引用传递给对象

不要从函数返回指针,将对象作为非const引用传递并更改这些对象

在堆上创建本地对象时,请使用scoped_ptr