在解释问题之前,我想指出我知道给定的示例是糟糕的代码。我已经在看std::shared_ptr
以更合理的方式实现我的目标。写这篇文章的原因只是我的好奇心和学习新东西的愿望。预先感谢您的帮助!
今天我的解析器代码有点混乱。优化的东西等等。我专注于一些在解析过程中不必要地克隆的对象实例。我无意中创建了一些全局实例并通过静态方法访问它们。无论如何(强烈简化)我以这个有点有趣的案例结束:
class class_a
{
class_a();
class_a& referenceToObject;
};
class_a& getGlobalObject();
class_a::class_a()
:referenceToObject(getGlobalObject())
{}
class_a object;
class_a object2;
class_a& getGlobalObject()
{
return object2;
}
这显然意味着我做了很多非常错误的事情,但在这个分支,优化是最重要的事情。
我感兴趣的是在更广泛的编译器集合中这样的代码会发生什么。GetGlobalObject()
返回对未调用其构造函数的对象的引用。它仍然只返回引用 - 即指向编译时已知的内存空间(数据段或堆上的某个位置,不知道)的指针。
假设没有任何东西会调用任何方法或任何成员object2
参考,这个例子是未定义的行为吗?
是的,传递对尚未构造的对象的引用是完全合法的,甚至以某些有限的方式使用此类引用。
[basic.life] ...类似地,在对象的生命周期开始之前但在该对象将占用的存储空间已分配之后,或者在对象的生命周期结束之后且在重用该对象占用的存储空间之前或释放时,任何引用原始对象的左值都可以使用,但只能以有限的方式使用。对于正在构造或销毁的对象,请参阅[class.cdtor]。否则,这样的左值引用分配的存储([basic.stc.dynamic.allocation]),并且使用不依赖于其值的左值的属性是明确定义的。如果出现以下情况,则程序具有未定义的行为:
(7.1) 泛左值用于访问对象,或者
(7.2) 泛左值用于调用对象的非静态成员函数,或者
(7.3) 泛左值绑定到对虚拟基类 ([dcl.init.ref]) 的引用,或者
(7.4) 左值用作 a 的操作数dynamic_cast
([expr.dynamic.cast]) 或作为操作数typeid
.
只要你不做上述任何事情,你就没有危险。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)