我正在阅读C ++ Faq Second Edition,常见问题解答第32.08页。
FAQ表示const引用传递的参数和const引用返回的参数可能导致悬空引用。
但如果参数通过引用传递并通过引用返回,则可以。
我知道在const引用的情况下它是不安全的,但是当参数是非const引用时它是如何安全的。
最后一行常见问题解答说 “请注意,如果函数通过非const引用接受参数(例如,f(string& s)),则返回此引用参数的副本是安全的,因为临时不能通过非const引用传递。”
需要对此有所了解!!
答案 0 :(得分:31)
如果你喜欢
const Foo & bar(const Foo &f) { return f; }
并将其称为
const Foo &ret = bar(Foo());
这个编译,但问题是现在'ret'是一个悬空引用,因为调用Foo()创建的临时对象在bar返回后被释放。这里详细的执行顺序是:
但是,如果您将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引用的文章都会让你对此有所了解。