引用相对于其目标的生存期
The lifetime of a reference with regard to its target
为了阻止我最近给出的答案评论中的争论,我想对以下问题给出一些建设性的答案:
- 引用的生存期与其引用的对象不同吗?引用只是其目标的别名吗
- 在一个格式良好的程序中,引用是否能在不导致未定义行为的情况下超过其目标
- 如果为原始对象分配的存储被重用,是否可以引用以引用新对象
- 以下代码是否在不调用未定义行为的情况下演示了上述要点
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
}
引用的生存期与其引用的对象不同吗?引用只是其目标的别名吗?
引用有其自身的生命周期:
int x = 0;
{
int& r = x;
} // r dies now
x = 5; // x is still alive
引用-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
尽管这并非没有警告:
如果引用是A)本地的,并且b)绑定到其求值创建所述临时对象的prvalue,则对const的引用仅延长临时对象的生存期。(因此,它不适用于绑定到xvalues的成员或本地引用。)此外,非常量右值引用以完全相同的方式延长生存期[@FredOverflow]
在一个格式良好的程序中,引用是否能在不导致未定义行为的情况下超过其目标?
当然,只要你不使用它。
如果为原始对象分配的存储被重用,是否可以引用以引用新对象?
是的,在某些条件下:
[C++11: 3.8/7]:
如果在对象的生存期结束后,在对象所占用的存储被重用或释放之前,在原始对象所占据的存储位置创建了一个新对象、指向原始对象的指针、引用原始对象的引用或原始对象的名称对象将自动引用新对象,并且一旦新对象的生存期开始,就可以用于操作新对象,如果:
- 新对象的存储正好覆盖原始对象所占用的存储位置,以及
- 新对象与原始对象的类型相同(忽略顶级cv限定符),并且
- 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型是const限定或引用类型的非静态数据成员,并且
- 原始对象是T类型的最派生对象(1.8),而新对象是T型的最派生的对象(即它们不是基类子对象)
以下代码是否在不调用未定义行为的情况下演示了上述要点?
Tl;dr
-
是的。例如,本地非静态引用具有自动存储持续时间和相应的生存时间,并且可以引用生存时间更长的对象。
-
是的,悬挂引用就是一个例子。只要这些引用在悬空时不用于任何表达式,它们就可以了。
-
关于这种情况,第3条有一条特别规定。对象、指针和引用的名称会自动引用在受限条件下重用存储的新对象。我相信已经是3.8的末尾了。有人手头有规格,请在这里填写正确的参考号。
- GCC对可能有效的代码抛出init list生存期警告
- 在不复制临时对象的情况下延长其生存期
- 结束另一个线程中使用的对象的生存期
- "this"指针的值在对象的生存期内是否恒定?
- 创建具有全局生存期的 UObject
- C++17 和静态临时生存期的参考扩展
- 数组对象的生存期是否在重用其元素存储时结束?
- 共享指针生存期
- 具有空洞初始化的对象的生存期
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 指针引用的生存期(以 C++为单位)
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- 对象存在与对象生存期不同吗
- 指向对象生存期之外的已分配内存的指针是"invalid pointer[s]"还是"pointer[s] to an object"?
- 全局静态生存期?他们会让你的程序崩溃吗?
- "std::function"的简单版本:函数对象的生存期?
- 您能否根据是否使用返回值来保证不同的生存期行为?
- 引用相对于其目标的生存期
- 目标C "autorelease" C++ -- 控制对象生存期的标准方法?