通过引用传递智能指针

时间:2013-06-28 15:46:22

标签: c++ visual-studio-2005

智能指针通常很小,因此通过值传递不是问题,但是将引用传递给它们是否存在任何问题;或者更确切地说,是否有特定情况不能这样做?

我正在编写一个包装器库,我的几个类将智能指针对象包装在底层库中...我的类不是智能指针,但API当前按值传递智能指针对象。

例如当前代码:

void class::method(const AnimalPtr pAnimal) { ... }

成为

void class::method(const MyAnimal &animal){...}

其中MyAnimal是封装AnimalPtr的新包装类。

无法保证Wrapper类有一天不会超越包装智能指针,所以通过值传递让我感到紧张。

2 个答案:

答案 0 :(得分:23)

在大多数情况下,你通过引用而不是值传递共享指针。虽然std::shared_ptr的大小很小,但复制的成本涉及原子操作(概念上是原子增量和销毁副本时的原子减量,尽管我相信某些实现设法进行非原子增量)。

在其他情况下,例如std::unique_ptr您可能更愿意按值传递,因为副本必须是一个移动而且它明确文档对象的所有权转移到函数(如果您不想转移所有权,则将引用传递给真实对象,而不是std::unique_ptr)。

在其他情况下,您的里程可能会有所不同。您需要知道复制的语义对于智能指针是什么,以及您是否需要来支付成本。

答案 1 :(得分:3)

通过引用传递智能指针是可以的,除非它是构造函数。在构造函数中,可以存储对原始对象的引用,这违反了智能指针的约定。如果你这样做,你可能会得到内存损坏。即使您的构造函数今天没有存储引用,我仍然会保持警惕,因为代码更改,如果您稍后决定需要更长时间地保存变量,则很容易错过。

在普通函数中,您不能将函数参数存储为任何位置的引用,因为必须在初始化期间设置引用。您可以将引用分配给一些较长寿的非引用变量,但这将是一个副本,因此会适当地增加其生命周期。所以在任何一种情况下,当调用函数可能释放它时,你无法保持它。在这种情况下,您可以使用引用获得较小的性能提升,但在大多数情况下我不会计划注意它。

所以我会说 - 构造函数,总是按值传递;其他功能,如果你愿意,可以通过引用传递。