const引用返回的const引用传递的参数

时间:2009-03-20 18:34:43

标签: c++

我正在阅读C ++ Faq Second Edition,常见问题解答第32.08页。

FAQ表示const引用传递的参数和const引用返回的参数可能导致悬空引用。

但如果参数通过引用传递并通过引用返回,则可以。

我知道在const引用的情况下它是不安全的,但是当参数是非const引用时它是如何安全的。

最后一行常见问题解答说 “请注意,如果函数通过非const引用接受参数(例如,f(string& s)),则返回此引用参数的副本是安全的,因为临时不能通过非const引用传递。”

需要对此有所了解!!

4 个答案:

答案 0 :(得分:31)

如果你喜欢

const Foo & bar(const Foo &f) { return f; }

并将其称为

const Foo &ret = bar(Foo());

这个编译,但问题是现在'ret'是一个悬空引用,因为调用Foo()创建的临时对象在bar返回后被释放。这里详细的执行顺序是:

  1. 临时Foo已分配
  2. bar通过引用临时对象来调用
  3. bar返回参考
  4. 现在bar已经返回临时Foo被释放
  5. 当对象被销毁时,引用现在悬空
  6. 但是,如果您将Foo声明为

    Foo & bar(Foo &f) { return f; }
    

    然后编译器不会接受您的调用栏(Foo())。将临时对象传递给函数时,只能通过const引用或作为副本获取;这是语言定义的一部分。

答案 1 :(得分:3)

Temporaries可以通过const引用传递 - 当函数返回时,临时值被释放,因此调用者留下了悬空引用。

例如:

#include <iostream>

using namespace std;

int const& output( int const& x) 
{
    cout << x << endl;

    return x;
} 

int main ()
{
    int a = 1;

    int const& ref1 = output( a); // OK

    int const& ref2 = output(a+1); // bad

    return 0;
}

答案 2 :(得分:1)

我认为这个例子会有所帮助:

const int& f(const int& n)
{
    return n;
}

int f1(int& n)
{
    return n;
}


int main(int argc, char **argv)
{
    //Passing a reference to an anonymous object created by
    //the compiler to function f()
    const int& n = f(10);

    //Undefined behavior here as the scope of the anonymous object
    //was only till previous statement
    int k = n + 10;

    //Compiler error - Can not pass non-const reference to a anonymous object
    int n = f1(10);
}

答案 3 :(得分:1)

Here是一个关于C ++ 0x rvalue引用的页面,它首先介绍了lvalues和rvalues如何在C ++中工作,以及如何允许它们与引用绑定。

大多数关于C ++ 0x中rvalue引用的文章都会让你对此有所了解。