返回一个参考以往任何时候都好主意吗?(Is returning a reference ever a

2019-08-01 22:45发布

我们都知道, 返回到本地变量的引用是一个坏主意 。 不过,我想知道如果这是有史以来真的是一个好主意,返回所有的引用,如果它能够确定什么时候或在不去做一些好的规则。

我与返回一个参考的问题是,调用函数需要关心的对象不应该是责任的寿命。 作为一个人为的例子:

#include <vector>

const int& foo() {
  std::vector<int> v = {1, 2, 3, 4, 5};
  return v[0];
}

int main(int argc, const char* argv[])
{
  const int& not_valid = foo();
  return 0;
}

这里, vector超出范围在年底foo ,破坏它的内容和无效它的元素的任何引用。 vector::operator[]返回到元素的引用,并且因此当该参考文献进一步返回出foo ,在参考main被悬空。 我不相信常量引用在这里延长寿命,因为它不是一个临时的参考。

正如我所说,这是一个人为的例子和作家foo可能就不会这么愚蠢的尝试和返回v[0]作为参考。 然而,很容易看到返回的引用要求调用者关心的对象不属于它的寿命。 推动元件成vector拷贝它,所以则vector是负责。 这个问题不存在传递一个引用参数,因为你知道来电者继续和销毁对象之前,该函数将完成。

我可以看到,返回一个引用允许像一些不错阵列状语法v[0] = 5 -但什么是坏大约具有象一个成员函数v.set(index, value) ? 至少在这一点,我们就不会露出内部的对象。 我知道,也可能是从返回参考的性能提升,但与RVO ,命名RVO(NRVO),和移动语义是微不足道或根本不存在。

所以我一直试图想象其下返回一个参考的情况是有史以来真正安全的,但我不能让我的头围绕所有权语义的所有不同的排列,它可能涉及。 有没有对的时候做这个有什么好的规则?

注:我知道一个更好的办法来应对所有权vector s是使用智能指针,但是你用不同的对象得到了同样的问题-谁拥有智能指针?

Answer 1:

有返回参考万吨的好用途。 其一是,如你所说,模仿类似的本地引用操作:

struct Goo
{
    int & operator[](size_t i) { return arr[i]; }
    int & front()              { return arr[0]; }

    // etc.

private:
    int * arr;
};

另一个用例是当您返回到中传递的事情参考典型的例子是像一个可链接的操作。 <<

std::ostream & operator<<(std::ostream & os, Goo const & g)
{ 
    return os << g[3];
}

作为最后一个例子,这里有一个线程安全的全局对象:

Goo & get_the_object()
{
    static Goo impl;
    return impl;
}

参考文献是语言的一个组成部分,他们可以很好地函数调用返回。 正如你所说的,了解对象的生命周期是很重要的,但是这总是正确的,而不是返回引用的一个特殊问题。



Answer 2:

就个人而言,我喜欢回到静态变量的引用,当我想要实现Singleton模式

SomeClass& getTheSingleton()
{
    static SomeClass theInstance;
    return theInstance;
}

我没有写任何逻辑涉及一些指针是否被初始化,它给了我在静态初始化的顺序一些控制



文章来源: Is returning a reference ever a good idea?