智能指针用法

时间:2010-12-29 12:20:54

标签: c++ pointers boost smart-pointers

我有一个项目,我希望更好地使用智能指针。

主要思想是在从函数返回新对象时使用它们。问题是使用什么智能指针?来自boost的 auto_ptr shared_ptr ?据我所知,auto_ptr较慢,但它可以回退到'纯'指针。

如果我在不需要它的地方使用智能指针,会不会使性能变慢?

5 个答案:

答案 0 :(得分:12)

是什么让您认为auto_ptrshared_ptr慢?通常情况下,我认为反之亦然,因为shared_ptr需要更新引用计数。

至于你应该使用哪种,不同的智能指针意味着不同的所有权语义。所有权意味着在不再需要时删除对象的责任。

  • 原始指针隐含无所有权;一个正确使用智能指针的程序仍然可以在许多不需要所有权的地方使用原始指针(例如,如果你需要将一个对象的可选引用传递给一个函数,你经常会使用一个原始指针)。
  • scoped_ptr表示(即非共享),不可转让所有权。
  • auto_ptr表示(即非共享)可转让所有权。这是我用来从函数返回一个新构造的对象的智能指针(该函数是对象传递给它的调用者)。 auto_ptr的缺点是,由于语言的限制,auto_ptr被定义时很难正确使用(这使得它的名声非常糟糕,尽管智能指针的预期目的是单一的,可转让的所有权语义是有效且有用的。)
  • unique_ptrauto_ptr具有相同的语义,但使用新的C ++ 0x功能(rvalue引用)使其比auto_ptr更安全(不易使用) 。如果您在unique_ptr可用的平台上进行开发,则应使用它而不是auto_ptr
  • shared_ptr表示共享所有权。在我看来,这是过度使用。它确实有许多有效用途,但只能用作默认选项。

我还要补充说shared_ptr经常与STL容器一起使用,因为其他智能指针类在该上下文中没有实现其预期的功能(由于在容器内部复制值)。这通常会导致使用shared_ptr,其中共享所有权并非真正意图。在这些情况下,我建议(尽可能)使用boost指针 - 容器类(ptr_vectorptr_map等),它们提供具有可转移的容器的(通常需要的)语义,但是单个(非共享)所有权。

您应该始终考虑对象的所有权:在大多数情况下,使用干净的系统设计,每个对象都有一个明显的所有者,并且不需要共享所有权。这样做的好处是很容易看到对象将被释放的确切位置和时间,并且不需要引用计数开销。

[已编辑以记录新的unique_ptr]

答案 1 :(得分:2)

您可能应该使用shared_ptr<>。如果不知道自己想要做什么,就很难更具体。最好阅读documentation并查看它是否符合您的要求。

性能差异很可能是微不足道的。只有在极端情况下才会产生明显的影响,比如每秒复制这些指针数百万次。

答案 2 :(得分:1)

我更喜欢shared_ptr,auto_ptr会造成很多麻烦,而且使用起来不太直观。如果您希望将此对象插入STL容器,那么您当然希望使用shared_ptr。

在性能方面取得成本,但这是最小的,你可以在大多数时间忽略它。

答案 3 :(得分:1)

取决于。
共享指针比auto_ptr更有用,它具有改变赋值所有权的不寻常特征 auto_ptr也不能用在容器中 如果您不想转让所有权,也不能将auto_ptr用作返回值 共享指针具有智能指针的所有好处,重载相关运算符以像指针一样操作并且可以在容器中使用。 话虽如此,它们使用起来并不便宜 您必须通过避免shared_pointer实现开销来分析您的需求,以确定您是否真正获得了某些东西

答案 4 :(得分:0)

仅使用shared_ptr。使用auto_ptr,您只能有一个对象的引用。 auto_ptr也不慢,它必须比shared_ptr更快。

不要问这些问题,你需要知道这些智能指针的工作原理。

auto_ptr只是存储指向你对象的指针并在它的析构函数中销毁它。

auto_ptr的问题在于,当您尝试复制它时,它会停止指向您的对象。

例如

auto_ptr a_ptr(new someClass);

auto_ptr another_ptr = aptr; //在此之后,another_ptr指向你的类,但a_ptr不再指向它了!

这就是为什么我不建议你使用auto_ptr。

共享指针计算智能指针指向您的对象的数量,并在没有更多指针时销毁您的对象。这就是为什么你可以有超过1个指针指向你的对象。

但共享指针也不完美。如果在你的程序中你有循环图(当你有A和B类,而A有一个成员shared_ptr,指向B和B有或B的成员对象有指向A的shared_ptr),A和B将永远不会删除,你会有记忆舔。

要使用shared_ptr编写正确的代码,您需要小心并使用weak_ptr。 有关详细信息,请查看此处http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/smart_ptr.htm