将const引用返回到智能指针vs使用引用作为参数

时间:2013-10-17 12:32:59

标签: c++ pointers reference

我们使用C ++ 98(旧版本)。

假设我们有一张桌子并考虑查找。 Ptr是一些智能指针。 声明1. - .3以下是正确的还是两种情况都是同等安全/不安全的 从来电者的角度来看?

查找的函数原型:

const Y::Ptr & lookup(const X::Ptr & x);

调用查找的调用函数:

const Y::Ptr & ret = lookup(x);

其中x是X :: Ptr对象或X :: Ptr的引用。因此,我们根据以上两行提供以下用法。

  1. 函数参数const X::Ptr &。这通常是安全的,并且在进行函数调用时避免使用X::Ptr的复制构造函数。调用者负责保持对象X的{​​{1}}引用以持续查找函数调用的持续时间。
  2. 返回值X。这是不安全的,因为在此引用位于堆栈上的短暂持续时间内,如果线程被中断/挂起而另一个线程从表中删除该条目,则Y对象和const Y::Ptr &对象都将被删除。因此,堆栈上的Y::Ptr引用引用了一个已消失的Ptr对象。
  3. 本地引用Y::Ptr用于存储查找的返回值。由于#2的类似原因,这是不安全的,但可能更糟,因为调用函数中此本地引用的范围比堆栈上的ref更长作为返回值。

2 个答案:

答案 0 :(得分:0)

我认为你说得对。显然,解决方案是按值返回智能指针。请注意,您的第2点完全被#3包含,所以没有必要特别考虑第2点(因为没有任何意义,您没有 - 或者不能使用引用)。

答案 1 :(得分:0)

很大程度上取决于lookup做了什么,以及你想要做什么 实现。您是否在逻辑上返回值或引用 一些内部数据?在很多具有名称的函数中 像lookup一样,它是后者,而且通常很重要 返回值是一个参考。 (一个明显的例子是 像operator[]中的std::vector这样的函数。)除非 语义需要引用,但是,你最好 按价值返回。

类似,在通话网站。如果调用者需要引用 你的数据结构,他应该声明变量 参考;否则,他应该宣布它是一个价值。 (的 当然,如果函数返回一个值,那么从来没有 合理的情况,其中局部变量应该是一个参考。)

我认为多线程在这里是一个红色的鲱鱼。如果是其他线程 正在修改数据结构lookup使用,您需要 外部同步,期间。如果函数返回 一个参考,你把它作为参考,然后是关键 section包含引用的生命周期,但这是 一般不是一个大问题;如果是,呼叫者可以存储 结果作为一个值,并用它来完成。

作为一般规则,C ++更喜欢值语义。语言是 考虑到这一点进行了优化,包括允许的特殊规则 编译器优化出不必要的副本。不要打架 它。关于唯一的例外是使用引用 const用于函数参数。 (但即使在这里,你也想成为 是一致的。无处不在的约定是传递类类型 引用const,其他类型的值。如果这是规则 在你的代码中使用,然后系统地使用它,没有 异常。)