我们使用 C++98(旧版本)。
假设我们有一个表并考虑查找。Ptr 是一些智能指针。从调用者的角度来看,以下语句 1. - .3 是否正确或考虑的两种情况同样安全/不安全?
查找函数原型:
const Y::Ptr & lookup(const X::Ptr & x);
以及调用查找的调用者函数:
const Y::Ptr & ret = lookup(x);
其中 x 是 X::Ptr 对象或 X::Ptr 的引用。因此,基于上面的 2 行,我们有以下用法。
- 函数参数
const X::Ptr &
。这通常是安全的,并且避免X::Ptr
了函数调用时的复制构造函数。调用者负责在查找函数调用期间保持X
对象的引用X
以持续。 - 返回值
const Y::Ptr &
。这是不安全的,因为在此引用在堆栈上的短暂持续时间内,如果线程被中断/挂起并且另一个线程从表中删除条目,则 Y 对象和Y::Ptr
对象都将被删除。结果,Y::Ptr
堆栈上的引用引用了一个消失的 Ptr 对象。 const Y::Ptr &
用于存储查找返回值的本地引用。这不安全,原因与 #2 类似,但可能更糟,因为调用者函数中的本地引用的范围比堆栈上作为返回值的 ref 更长。