在解释我想要标记的问题之前,我知道给出的例子是错误的代码。我已经在考虑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()
正在返回对没有调用构造函数的对象的引用。它仍然只返回引用 - 这是指向编译时已知的内存空间(数据段或堆上某处,dunno)的指针。
假设没有任何方法可以调用任何方法或object2
引用的任何成员,这个示例是未定义的行为吗?
答案 0 :(得分:11)
是的,传递对尚未构建的对象的引用是完全合法的,甚至以某些有限的方式使用这些引用。
[basic.life] ...类似地,在对象的生命周期开始之前但是在对象占用的存储之后已经分配了,或者在对象的生命周期结束之后以及在对象的存储之前被占用被重用或释放,任何引用原始对象的glvalue都可以使用,但只能以有限的方式使用。对于正在构建或销毁的对象,请参阅[class.cdtor]。否则,这样的glvalue指的是已分配的存储([basic.stc.dynamic.allocation]),并且使用不依赖于其值的glvalue的属性是明确定义的。如果出现以下情况,该程序的行为未定义:
(7.1)glvalue用于访问对象,或
(7.2)glvalue用于调用对象的非静态成员函数,或者
(7.3)glvalue绑定到对虚基类的引用([dcl.init.ref]),或者
(7.4)glvalue用作dynamic_cast
([expr.dynamic.cast])的操作数或typeid
的操作数。
只要你没有做上述任何事情,你就是明确的。