关于其目标的参考的生命周期

Jos*_*eld 6 c++ reference object-lifetime undefined-behavior

为了阻止我最近给出的答案评论中的论点,我想对以下问题作一些建设性的答案:

  1. 参考的生命周期是否与它所指的对象不同?引用只是其目标的别名吗?
  2. 引用是否可以在格式良好的程序中比其目标更长,而不会导致未定义的行为?
  3. 如果重用为原始对象分配的存储,是否可以引用新对象?
  4. 以下代码是否在不调用未定义行为的情况下演示了上述几点?

Ben Voigt和简化示例代码(在ideone.com运行):

#include <iostream>
#include <new>

struct something
{
    int i;
};

int main(void)
{
    char buffer[sizeof (something) + 40];
    something* p = new (buffer) something;
    p->i = 11;
    int& outlives = p->i;
    std::cout << outlives << "\n";
    p->~something(); // p->i dies with its parent object
    new (p) char[40]; // memory is reused, lifetime of *p (and p->i) is so done
    new (&outlives) int(13);
    std::cout << outlives << "\n"; // but reference is still alive and well
                                   // and useful, because strict aliasing was respected
}
Run Code Online (Sandbox Code Playgroud)

Lig*_*ica 10

参考的生命周期是否与它所指的对象不同?引用只是其目标的别名吗?

引用有自己的生命周期:

int x = 0;
{
   int& r = x;
}      // r dies now
x = 5; // x is still alive
Run Code Online (Sandbox Code Playgroud)

一个REF-TO- const另外可以延伸它的裁判的寿命:

int foo() { return 0; }
const int& r = foo();   // note, this is *not* a reference to a local variable
cout << r;              // valid; the lifetime of the result of foo() is extended
Run Code Online (Sandbox Code Playgroud)

虽然这不是没有警告:

如果引用是a)local而b)绑定到其评估创建所述临时对象的prvalue,则对const的引用仅延长临时对象的生命周期.(因此它不适用于成员或绑定到xvalues的本地引用.)此外,非const rvalue引用以完全相同的方式扩展生命周期.[@FredOverflow]


引用是否可以在格式良好的程序中比其目标更长,而不会导致未定义的行为?

当然,只要你不使用它.


如果重用为原始对象分配的存储,是否可以引用新对象?

是的,在某些情况下:

[C++11: 3.8/7]: 如果在对象的生命周期结束之后并且在重用或释放对象占用的存储之前,则在原始对象占用的存储位置创建新对象,指向原始对象的指针,引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,就可以用来操纵新对象,如果:

  • 新对象的存储完全覆盖原始对象占用的存储位置,以及
  • 新对象与原始对象的类型相同(忽略顶级cv限定符),和
  • 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为const限定的非静态数据成员或引用类型,以及
  • 原始对象是类型为T的派生程度最高的对象(1.8),新对象是类型为T的派生程度最高的对象(也就是说,它们不是基类子对象).

以下代码是否在不调用未定义行为的情况下演示了上述几点?

文艺青年最爱的.


Joh*_*itb 5

  1. 是.例如,本地非静态引用具有自动存储持续时间和相应的生命周期,并且可以引用具有更长寿命的对象.

  2. 是的,悬空参考就是一个例子.只要这些引用在它们变得悬空时不用于任何表达式,它们就可以了.

  3. 关于这个案子,第3条有一条特殊规则.对象,指针和引用的名称自动引用在受限条件下重用存储的新对象.我相信它是在3.8的结尾.有规格的人请在这里填写正确的参考.