oli*_*bre 5 c++ scope reference const-reference temporary-objects
在提出这个问题的时候,我学会了对一个临时对象的const引用在C++中是有效的:
int main ()
{
int a = 21;
int b = 21;
//error: invalid initialization of non-const reference
//int & sum = a + b;e [...]
//OK
int const & sum = a + b;
return sum;
}
Run Code Online (Sandbox Code Playgroud)
但在下面的示例中,const引用refnop引用了一个被销毁的临时对象.我想知道为什么?
#include <string>
#include <map>
struct A
{
// data
std::map <std::string, std::string> m;
// functions
const A& nothing() const { return *this; }
void init() { m["aa"] = "bb"; }
bool operator!= (A const& a) const { return a.m != m; }
};
int main()
{
A a;
a.init();
A const& ref = A(a);
A const& refnop = A(a).nothing();
int ret = 0;
if (a != ref) ret += 2;
if (a != refnop) ret += 4;
return ret;
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 4.1.2和MSVC 2010进行测试,返回4;
$> g++ -g refnop.cpp
$> ./a.out ; echo $?
4
Run Code Online (Sandbox Code Playgroud)
ref和之间的区别refnop是nothing()什么都没有.看来这个调用后,临时对象被破坏了!
我的问题:
为什么在这种情况下refnop,临时对象的生命周期与它的const引用不一样?
Bar*_*nau 10
当临时对象绑定到第一个引用时,临时对象的生存期扩展只能执行一次.之后,引用引用临时对象的知识消失了,因此无法进一步扩展生命周期.
令你困惑的案例
A const& refnop = A(a).nothing();
Run Code Online (Sandbox Code Playgroud)
类似于这种情况:
A const& foo(A const& bar)
{
return bar;
}
//...
A const& broken = foo(A());
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,临时绑定到函数参数(隐式thisfor nothing(),barfor foo())并将其生命周期'扩展'到函数参数的生命周期.我将'扩展'放在引号中,因为临时的自然生命周期已经更长,因此不会发生实际的扩展.
由于寿命延长属性是非传递,返回一个参考(即恰好是指一个临时对象)将不会进一步延长临时对象的生存期,以作为结果,这两个refnop和broken最后指不再存在的对象.