函数范围(生命周期)后,对临时对象的const引用被破坏 [英] const reference to a temporary object becomes broken after function scope (life time)

查看:112
本文介绍了函数范围(生命周期)后,对临时对象的const引用被破坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题时,我学会了const引用临时对象在C ++中有效:

While asking this question, I learned const reference to a temporary object is valid in 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;
}

但是在下面的示例中,const引用refnop引用了已损坏的临时对象.我想知道为什么吗?

But in the following example, the const reference refnop refers to a destroyed temporary object. I wonder why?

#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;
}

使用GCC 4.1.2和MSVC 2010进行测试,返回4;

Tested using GCC 4.1.2 and MSVC 2010, it returns 4;

$> g++ -g refnop.cpp
$> ./a.out ; echo $?
4

refrefnop之间的区别是对nothing()的调用,它实际上没有任何作用.似乎在此调用之后,临时对象被破坏了!

The difference between ref and refnop is the call to nothing() which does really nothing. It seems after this call, the temporary object is destroyed!

我的问题:
为什么在refnop情况下,临时对象的生存期与其常量引用不同?

My question:
Why in the case of refnop, the life time of the temporary object is not the same as its const reference?

推荐答案

当临时对象绑定到第一个引用时,临时对象的生存期扩展只能执行一次.此后,该引用引用了一个临时对象的知识就消失了,因此无法进一步延长生命周期.

The lifetime-extension of a temporary object can be performed only once, when the temporary object gets bound to the first reference. After that, the knowledge that the reference refers to a temporary object is gone, so further lifetime extensions are not possible.

令人困惑的案子

A const& refnop = A(a).nothing();

类似于这种情况:

A const& foo(A const& bar)
{
    return bar;
}
//...
A const& broken = foo(A());

在两种情况下,临时变量都绑定到函数参数(对于nothing()而言是隐式的this,对于foo()而言是bar),并将其生存期扩展"到了函数参数的生存期.我将"extended"用引号引起来,因为临时文件的自然寿命已经更长,因此没有实际的扩展发生.

In both cases, the temporary gets bound to the function argument (the implicit this for nothing(), bar for foo()) and gets its lifetime 'extended' to the lifetime of the function argument. I put 'extended' in quotes, because the natural lifetime of the temporary is already longer, so no actual extension takes place.

由于生存期扩展属性是非传递性的,因此返回引用(恰好引用临时对象)将不会进一步延长临时对象的生存期,结果refnopbroken都结束指向不再存在的对象.

Because the lifetime extension property is non-transitive, returning a reference (that happens to refer to a temporary object) will not further extend the lifetime of the temporary object, with as result that both refnop and broken end up referring to objects that no longer exist.

这篇关于函数范围(生命周期)后,对临时对象的const引用被破坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆