问题描述
为了阻止我最近给出的答案的评论中的争论,我想要一些对以下问题的建设性回答:
- 引用的生命周期与它所引用的对象不同吗?引用仅仅是其目标的别名吗?
- 引用能否在格式良好的程序中比其目标存活时间更长,而不会导致未定义的行为?
- 如果重用为原始对象分配的存储空间,是否可以进行引用以引用新对象?
- 以下代码是否在不调用未定义行为的情况下演示了上述要点?
Ben Voigt 的示例代码并简化(在 ideone.com):
#include #include <new>构造一些东西{国际我;};int main(void){字符缓冲区[sizeof (something) + 40];某物* p = 新(缓冲)某物;p->i=11;内部&寿命 = p-> i;std::cout <<寿命<~something();//p->i 与其父对象一起死亡新 (p) 字符 [40];//内存被重用,*p(和 p->i)的生命周期就这样完成了new (&outlives) int(13);std::cout <<寿命<
引用有自己的生命周期:
int x = 0;{内部&r = x;}//r 现在死了x = 5;//x 还活着
ref-to-const
还可以延长其裁判的生命周期:
int foo() { return 0;}const int&r = foo();//注意,这不是对局部变量的引用cout<<r;//有效的;foo() 结果的生命周期被延长
尽管这并非没有警告:
对 const 的引用仅在引用 a) 本地且 b) 绑定到其评估创建所述临时对象的纯右值时才延长临时对象的生命周期.(因此它不适用于成员或绑定到 xvalues 的本地引用.)此外,非常量 rvalue 引用以完全相同的方式延长生命周期.[@FredOverflow]
引用能否在格式良好的程序中比其目标存活时间更长,而不会导致未定义的行为?
当然,只要你不使用它.
如果为原始对象分配的存储被重用,是否可以进行引用以引用新对象?
是的,在某些情况下:
[C++11: 3.8/7]:
如果在一个对象的生命周期结束之后,并且在该对象占用的存储空间被重用或释放之前,一个新的对象在原始对象占用的存储位置、指向原始对象的指针、引用原始对象的引用或原始对象的名称object 将自动引用新对象,并且一旦新对象的生命周期开始,可用于操作新对象,如果:
- 新对象的存储与原始对象占用的存储位置完全重叠,并且
- 新对象与原始对象的类型相同(忽略顶级 cv 限定符),并且
- 原始对象的类型不是 const 限定的,并且,如果是类类型,则不包含任何类型为 const 限定或引用类型的非静态数据成员,并且
- 原始对象是 T 类型的最派生对象 (1.8),而新对象是 T 类型的最派生对象(即,它们不是基类子对象).
以下代码是否在不调用未定义行为的情况下演示了上述要点?
Tl;博士
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:
- Is a reference's lifetime distinct from the object it refers to? Is a reference simply an alias for its target?
- 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?
- Does the following code demonstrate the above points without invoking undefined behaviour?
Example code by Ben Voigt and simplified (run it on 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
}
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:
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:
Sure, as long as you don't use it.
Yes, under some conditions:
Tl;dr.
这篇关于引用相对于其目标的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!