Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类,该类包含对自身的引用_C++_Language Lawyer - Fatal编程技术网

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:是否允许定义这种类型的对象,并

在浏览标准草案(n3242)时,我在第9.2条(重点)中发现了这句话:

非静态(9.4)数据成员的类型不得不完整。在里面 特别是,C类不应包含C类的非静态构件 C、 但它可以包含指向类对象的指针或引用 C

因此,我认为可以这样定义一个类:

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。然后您应该创建一个方法,在这里您可以将指针设置为一个给定的值,在您的例子中是一个指向自身的指针。如果你不介意的话,你可以在构造函数中设置引用,因为对象已经被创建了