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

标签 c++ reference undefined-behavior object-lifetime

为了阻止在 an answer I gave recently 的评论中进行的争论, 我想要对以下问题的一些建设性答案:

  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
}

最佳答案

Is a reference's lifetime distinct from the object it refers to? Is a reference simply an alias for its target?

引用有自己的生命周期:

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

ref-to-const 还可以延长其 refere 的生命周期:

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

虽然这并非没有警告:

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. (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. [@FredOverflow]


Can a reference outlive its target in a well-formed program without resulting in undefined behaviour?

当然可以,只要你不使用它。


Can a reference be made to refer to a new object if the storage allocated for the original object is reused?

是的,在某些情况下:

[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:

  • 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
  • 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
  • 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).

Does the following code demonstrate the above points without invoking undefined behaviour?

Tl;博士

关于c++ - 引用相对于其目标的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9291371/

相关文章:

c++ - 使用 files_put 上传 DropBox 返回身份验证失败

c++ - std::sort - 是否传递了错误的比较器未定义行为?

C++ 级联破坏具有静态存储持续时间的对象

c++ - 非静态成员函数的 decltype 格式不正确吗?

c++ - 错误 C2059 : syntax error: 'constant' from struct member declarations

c++ - 从 dynamic_cast 获取非常量引用

c++ - 对 int 的本地引用有什么好处吗?

c - 为什么 "int x = 5; printf("%d %d %d", x==5, x=10, x==5) ;"in C print "0 10 0"?

c++ - 为什么 adl 更喜欢 'boost::range_detail::operator|' 而不是本地 'operator|'?

c++ - 为什么我应该按值返回一些东西,因为 C++ 具有 const 引用?