C++ 类,该类包含对自身的引用
在浏览标准草案(n3242)时,我在第9.2条(重点)中发现了这句话: 非静态(9.4)数据成员的类型不得不完整。在里面 特别是,C类不应包含C类的非静态构件 C、 但它可以包含指向类对象的指针或引用 C 因此,我认为可以这样定义一个类:C++ 类,该类包含对自身的引用,c++,language-lawyer,C++,Language Lawyer,在浏览标准草案(n3242)时,我在第9.2条(重点)中发现了这句话: 非静态(9.4)数据成员的类型不得不完整。在里面 特别是,C类不应包含C类的非静态构件 C、 但它可以包含指向类对象的指针或引用 C 因此,我认为可以这样定义一个类: class A { public: A(A& a) : a_(a){ } private: A& a_; }; 然后,在第8.3.2条中,我发现以下内容: 引用应初始化为引用有效对象或 作用 问题1:是否允许定义这种类型的对象,并
class A {
public:
A(A& a) : a_(a){
}
private:
A& a_;
};
然后,在第8.3.2条中,我发现以下内容:
引用应初始化为引用有效对象或
作用
问题1:是否允许定义这种类型的对象,并将其名称作为引用传递:
A a(a);
还是会触发未定义的行为
问题2:如果是,标准中哪些部分允许从待构建对象初始化引用
问题3:如果否,这是否意味着类A的定义格式良好,但在不触发UB的情况下无法创建第一个对象?在这种情况下,这背后的基本原理是什么?n3337§3.8/6 类似地,在对象的生存期开始之前但在 对象将占用的存储已分配,或者 对象的生存期已结束,在 对象占用被重用或释放,任何引用 可以使用原始对象,但只能以有限的方式使用。对于一个对象 正在施工或破坏中,见12.7。否则,这样的值 指已分配的存储(3.7.4.2),并使用 不依赖于其值的glvalue是定义良好的。节目 具有未定义的行为,如果: -左值到右值的转换(4.1)是 适用于这样一个值 -glvalue用于访问 非静态数据成员或调用的非静态成员函数 反对,或 -glvalue隐式转换(4.10)为引用 到基类类型,或 -glvalue用作 静态铸轧(5.2.9),除非最终转换为cv 字符(&C)或cv无符号字符(&C),或 -glvalue用作的操作数 动态_转换(5.2.7)或作为typeid的操作数 因此,要回答您的问题: 问题1:是否允许定义这种类型的对象 它的名字作为参考 对。仅使用地址似乎不会违反这一点(至少对于放在堆栈上的变量而言)
A(A)代码>
还是会触发未定义的行为
没有
问题2:如果是,标准中哪些部分允许
从仍要构造的对象初始化引用
§3.8/6(以上)
剩下的唯一问题是,这与
引用应初始化为引用有效对象或
功能
问题在于术语“有效对象”。因为§§§§8.3.2/4说
未指定引用是否需要存储
看来,§8.3.2有问题,应该重新编写。混乱导致文件C++核心语言的主动性问题,修订版87日期为20.01.2014:
引用应初始化为引用对象或函数
将8.3.2[dcl.ref]第4段更改如下:
如果引用直接绑定到的左值既不指定
适当类型的现有对象或功能(8.5.3
[dcl.init.ref]),也不是适当大小和对齐的内存区域
包含引用类型的对象(1.8[intro.object],3.8
[basic.life],3.9[basic.types]),行为未定义
从n1905,3.3.1.1
名称的声明点在其完成后立即出现
声明人(第8条)及其初始设定人(如有)之前,除非
如下所示
[示例:
int x=12;
{int x=x;}
这是第二个x
用它自己的(不确定)值初始化
-[结束示例]
我的重点(如果我错了请纠正我):在你的例子中-
A a(a);
相当于-
A a = a; // Copy initialization
因此,根据标准a
用它自己的不确定值初始化。并且成员持有对一个这样的不确定值的引用。标准中没有定义“有效对象”,但它意指具有适当大小和对齐方式的内存区域,可以包含指定类型的对象。它只是意味着排除对诸如取消引用的空指针、未对齐的内存区域等的引用。未初始化的对象是有效的
有一个悬而未决的问题需要澄清措辞。你第一个问题的答案是否定的。在你想要定义“a”的时候,你还没有定义它,它就像鸡和蛋一样。应该使用空引用初始化对象,然后将引用设置为对象本身。对我来说,这种编程风格听起来有点可疑,但我不知道你们想实现什么。当获得存储并完成初始化时,对象的生命周期就开始了。如果这是“有效对象”的定义…@Sirac:什么是“空引用”?那么你如何设置引用呢?@Sirac这不是一个“编程风格”的问题,而是一个“语言律师”的问题。我试图理解的是与我引用的部分相关的标准的含义。我只是想用指针替换引用(有细微的区别,但我现在不知道),并将指针设置为NULL。然后您应该创建一个方法,在这里您可以将指针设置为一个给定的值,在您的例子中是一个指向自身的指针。如果你不介意的话,你可以在构造函数中设置引用,因为对象已经被创建了