简体   繁体   English

引用相对于其目标的生命周期

[英]The lifetime of a reference with regard to its target

In order to stem the argument going on in the comments of an answer I gave recently , I'd like some constructive answers to the following questions:为了阻止我最近给出的答案的评论中的争论,我想对以下问题提供一些建设性的答案:

  1. Is a reference's lifetime distinct from the object it refers to?引用的生命周期与它所引用的对象不同吗? Is a reference simply an alias for its target?引用仅仅是其目标的别名吗?
  2. Can a reference outlive its target in a well-formed program without resulting in undefined behaviour?在格式良好的程序中,引用能否比其目标存活时间更长,而不会导致未定义的行为?
  3. Can a reference be made to refer to a new object if the storage allocated for the original object is reused?如果为原始对象分配的存储被重用,是否可以进行引用以引用新对象?
  4. Does the following code demonstrate the above points without invoking undefined behaviour?以下代码是否在不调用未定义行为的情况下演示了上述要点?

Example code by Ben Voigt and simplified (run it on ideone.com ): 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
}

Is a reference's lifetime distinct from the object it refers to?引用的生命周期与它所引用的对象不同吗? Is a reference simply an alias for its target?引用仅仅是其目标的别名吗?

A reference has its own lifetime:一个引用有它自己的生命周期:

int x = 0;
{
   int& r = x;
}      // r dies now
x = 5; // x is still alive

A ref-to- const additionally may extend the lifetime of its referee: 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

though this is not without caveats:虽然这并非没有警告:

A reference to const only extends the lifetime of a temporary object if the reference is a) local and b) bound to a prvalue whose evaluation creates said temporary object.如果引用 a) 本地且 b) 绑定到其求值创建所述临时对象的纯右值,则对 const 的引用仅会延长临时对象的生命周期。 (So it doesn't work for members, or local references which are bound to xvalues.) Also, non-const rvalue references extend the lifetime in the exact same fashion. (因此它不适用于成员或绑定到 xvalues 的本地引用。)此外,非常量 rvalue 引用以完全相同的方式延长生命周期。 [@FredOverflow] [@FredOverflow]


Can a reference outlive its target in a well-formed program without resulting in undefined behaviour?在格式良好的程序中,引用能否比其目标存活时间更长,而不会导致未定义的行为?

Sure, as long as you don't use it.当然,只要你不使用它。


Can a reference be made to refer to a new object if the storage allocated for the original object is reused?如果为原始对象分配的存储被重用,是否可以进行引用以引用新对象?

Yes, under some conditions:是的,在某些条件下:

[C++11: 3.8/7]: If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if: [C++11: 3.8/7]:如果在一个对象的生命周期结束后,在该对象所占用的存储被重用或释放之前,在原对象所占用的存储位置创建一个新对象,指向原始对象的指针、引用原始对象的引用或原始对象的名称将自动引用新对象,一旦新对象的生命周期开始,可用于操作新对象对象,如果:

  • the storage for the new object exactly overlays the storage location which the original object occupied, and新对象的存储正好覆盖原始对象占用的存储位置,并且
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and新对象与原始对象的类型相同(忽略顶级 cv 限定符),并且
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and原始对象的类型不是 const 限定的,并且,如果是类类型,则不包含任何类型为 const 限定或引用类型的非静态数据成员,并且
  • the original object was a most derived object (1.8) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).原始对象是 T 类型的最派生对象 (1.8),而新对象是 T 类型的最派生对象(即,它们不是基类子对象)。

Does the following code demonstrate the above points without invoking undefined behaviour?以下代码是否在不调用未定义行为的情况下演示了上述要点?

Tl;dr. Tl;博士。

  1. Yes.是的。 For example local nonstatic references have automatic storage duration and corresponding liifetime and can refer to objects that have longer lifetime.例如本地非静态引用具有自动存储持续时间和相应的生命周期,并且可以引用具有更长生命周期的对象。

  2. Yes, dangling references are an example.是的,悬空引用就是一个例子。 As long as such references are not used in any expressions when they become dangling, they are fine.只要这样的引用在悬空时没有在任何表达式中使用,它们就可以了。

  3. There is a special rule in clause 3 about this case.第 3 条中有关于这种情况的特殊规则。 Names of objects, pointers and references automatically refer to the new object that reuses the storage under restricted conditions.对象名称、指针和引用自动引用在受限条件下重用存储的新对象。 I believe it is at the end of 3.8.我相信它是在 3.8 的末尾。 Someone who has the spec handy please fill in the correct ref here.手边有规范的人请在此处填写正确的参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM