我们使用C ++ 98(旧版本)。
假设我们有一张桌子并考虑查找。 Ptr是一些智能指针。 声明1. - .3以下是正确的还是两种情况都是同等安全/不安全的 从来电者的角度来看?
查找的函数原型:
const Y::Ptr & lookup(const X::Ptr & x);
调用查找的调用函数:
const Y::Ptr & ret = lookup(x);
其中x是X :: Ptr对象或X :: Ptr的引用。因此,我们根据以上两行提供以下用法。
const X::Ptr &
。这通常是安全的,并且在进行函数调用时避免使用X::Ptr
的复制构造函数。调用者负责保持对象X
的{{1}}引用以持续查找函数调用的持续时间。X
。这是不安全的,因为在此引用位于堆栈上的短暂持续时间内,如果线程被中断/挂起而另一个线程从表中删除该条目,则Y对象和const Y::Ptr &
对象都将被删除。因此,堆栈上的Y::Ptr
引用引用了一个已消失的Ptr对象。Y::Ptr
用于存储查找的返回值。由于#2的类似原因,这是不安全的,但可能更糟,因为调用函数中此本地引用的范围比堆栈上的ref更长作为返回值。答案 0 :(得分:0)
我认为你说得对。显然,解决方案是按值返回智能指针。请注意,您的第2点完全被#3包含,所以没有必要特别考虑第2点(因为没有任何意义,您没有 - 或者不能使用引用)。
答案 1 :(得分:0)
很大程度上取决于lookup
做了什么,以及你想要做什么
实现。您是否在逻辑上返回值或引用
一些内部数据?在很多具有名称的函数中
像lookup
一样,它是后者,而且通常很重要
返回值是一个参考。 (一个明显的例子是
像operator[]
中的std::vector
这样的函数。)除非
语义需要引用,但是,你最好
按价值返回。
类似,在通话网站。如果调用者需要引用 你的数据结构,他应该声明变量 参考;否则,他应该宣布它是一个价值。 (的 当然,如果函数返回一个值,那么从来没有 合理的情况,其中局部变量应该是一个参考。)
我认为多线程在这里是一个红色的鲱鱼。如果是其他线程
正在修改数据结构lookup
使用,您需要
外部同步,期间。如果函数返回
一个参考,你把它作为参考,然后是关键
section包含引用的生命周期,但这是
一般不是一个大问题;如果是,呼叫者可以存储
结果作为一个值,并用它来完成。
作为一般规则,C ++更喜欢值语义。语言是
考虑到这一点进行了优化,包括允许的特殊规则
编译器优化出不必要的副本。不要打架
它。关于唯一的例外是使用引用
const
用于函数参数。 (但即使在这里,你也想成为
是一致的。无处不在的约定是传递类类型
引用const,其他类型的值。如果这是规则
在你的代码中使用,然后系统地使用它,没有
异常。)