为了阻止an answer I gave recently的评论中提出的论点,我想对以下问题作出一些建设性的回答:
示例代码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
}
答案 0 :(得分:10)
引用的生命周期是否与它引用的对象不同?引用只是其目标的别名吗?
引用有自己的生命周期:
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)local而b)绑定到其评估创建所述临时对象的prvalue,则对const的引用仅延长临时对象的生命周期。 (因此它不适用于成员或绑定到xvalues的本地引用。)此外,非const rvalue引用以完全相同的方式扩展生命周期。 [@ FredOverflow]
引用可以在格式良好的程序中比其目标更长,而不会导致未定义的行为吗?
当然,只要你不使用它。
如果重用为原始对象分配的存储,是否可以引用新对象?
是的,在某些条件下:
[C++11: 3.8/7]:
如果在对象的生命周期结束之后,在重用或释放对象占用的存储之前,在原始对象占用的存储位置创建一个新对象,指向指针原始对象,引用原始对象的引用,或原始对象的名称 对象将自动引用新对象,并且一旦新对象的生命周期开始,就可以用来操作新对象,如果:
- 新对象的存储空间正好覆盖原始对象占用的存储位置,
- 新对象与原始对象的类型相同(忽略顶级cv限定符),
- 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为const-qualified或引用类型的非静态数据成员,并且
- 原始对象是类型为T的派生程度最高的对象(1.8),新对象是类型为T的派生程度最高的对象(即,它们不是基类子对象)。
以下代码是否在不调用未定义行为的情况下演示了上述几点?
铊;博士
答案 1 :(得分:5)
是。例如,本地非静态参考具有自动存储持续时间和相应的生命周期,并且可以指具有更长寿命的对象。
是的,悬空参考就是一个例子。只要这些引用在它们变得悬空时不用于任何表达式,它们就可以了。
第3条有关于此案的特别规则。对象,指针和引用的名称自动引用在受限条件下重用存储的新对象。我相信它是在3.8的结尾。有规格的人请在这里填写正确的参考文献。