3

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

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

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

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

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

当然,我可以在任何地方使用智能指针,这是最安全的选择,但我觉得这确实没有必要,而且会增加开销。

4

7 回答 7

5

恕我直言,有时做事更快比性能稍有改善要好。我想如果你总是使用智能指针,你会做得更快。

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

于 2009-07-13T15:09:44.180 回答
4

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

于 2009-07-13T15:20:37.390 回答
2

我的指针列表:

  • 正常用法:正常成员和对它们的 (const) 引用
  • 共享和保持对象存活(所有者、容器):shared_ptr
  • 共享,但不保持活力(用户):weak_ptr
  • 作用域用法:scoped_ptr
  • 其他用法(输出参数,...):原始指针
于 2009-07-13T15:47:15.713 回答
2

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

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

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

于 2009-07-13T15:16:12.873 回答
1

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

于 2009-07-13T15:20:44.800 回答
0

根据我的经验,当我将对象传递给不需要存储对象引用的函数时(或者,调用函数不会以任何方式影响对象的生命周期),那么它是安全的通过引用传递对象。这使得代码更少地“绑定”到智能指针类型。

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

于 2009-07-13T15:14:51.613 回答
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,否则不要:

不要传递指向函数的指针,传递对对象的引用

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

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

于 2009-07-13T16:02:26.820 回答