C++ 返回对智能指针的常量引用vs使用引用作为参数

C++ 返回对智能指针的常量引用vs使用引用作为参数,c++,pointers,reference,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的引用。因此,基于以上两行,我们有以下用法 函数参数常量X::Ptr&。这通常

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

我们假设有一个表并考虑查找。Ptr是一种智能指针。 这些是陈述1。3低于正确值,或两种情况被视为同等安全/不安全 从来电者的角度来看

查找的功能原型:

const Y::Ptr & lookup(const X::Ptr & x);
以及调用查找的调用方函数:

const Y::Ptr & ret = lookup(x);
其中x是x::Ptr对象或x::Ptr的引用。因此,基于以上两行,我们有以下用法

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

  • 我想你说得差不多对。显然,一个解决方案是按值返回智能指针。请注意,您的第2点完全包含在第3点中,因此无需特别考虑第2点(因为没有任何一点是您不使用或不能使用的引用)。

    很大程度上取决于
    查找
    的功能和您尝试使用的内容 实现逻辑上是否返回值或对的引用 一些内部数据?在很多情况下,函数都有名称 与查找类似,查找是后者,这一点通常很重要 返回值必须是一个引用。(一个明显的例子是 类似于
    std::vector
    中的
    运算符[]
    的函数,除非 语义需要一个引用,但是,您最好 按值返回

    类似的,在呼叫站点。如果调用方需要引用到 你的数据结构,他应该声明变量为 参考文献;否则,他应该声明它是一个值。(关于 当然,如果函数返回一个值,则永远不会有任何值 局部变量应作为参考的合理情况。)

    我认为多线程在这里是一种危险的做法。如果其他线程 正在修改数据结构
    查找
    使用,您需要
    外部同步,周期。如果函数返回
    一个参考,你把它作为参考,然后
    节包括引用的生存期,但这是
    一般来说不是什么大问题;如果是,调用方可以存储
    结果作为一个值,并用它来完成

    作为一般规则,C++更倾向于值语义。语言是 考虑到这一点进行了优化,包括允许 编译器将优化不必要的副本。不要打架 信息技术唯一的例外是使用对的引用 函数参数的常量。(但即使在这里,你也希望 一致性。普遍的约定是通过 引用常量,按值引用其他类型。如果这是规则 在代码中使用,然后系统地使用它,而不使用


    例外情况。)

    问题不仅在于参考值与价值,还在于初始帖子中描述的两种方法中哪一种更安全。