类中的“不完全types”,它具有与类本身types相同的成员

我有一个class级,应该有一个class级的私人成员,像这样:

class A { private: A member; } 

但它告诉我,成员是一个不完整的types。 为什么? 它不告诉我不完整的types,如果我使用一个指针,但我宁愿不使用指针。 任何帮助表示赞赏

当你声明你的成员时,你仍然定义A类,所以typesA仍然是未定义的。

但是,当你编写A* ,编译器已经知道A代表类名,所以定义了types“指向A的指针”。 这就是为什么你可以embedded一个指向你正在定义的types的指针。

同样的逻辑也适用于其他types,所以如果你只写:

 class Foo; 

你声明类Foo,但是你永远不会定义它。 你可以写:

 Foo* foo; 

但不是:

 Foo foo; 

另一方面,如果编译器允许recursion定义,那么对于typesA ,你会期望什么内存结构?

但是,它有时在逻辑上有效,有一个types,以某种方式引用另一个相同types的实例。 人们通常使用指针,甚至更好:智能指针(如boost::shared_ptr ),以避免不必处理手动删除。

就像是:

 class A { private: boost::shared_ptr<A> member; }; 

这是你想要实现的一个工作例子:

 class A { public: A() : a(new A()) {} ~A() { delete a; a = nullptr; } private: A* a; }; A a; 

快乐堆栈溢出!

A是“不完整的”,直到定义结束(尽pipe这不包括成员职能的机构)。

其中一个原因是,在定义结束之前,没有办法知道A有多大(取决于成员大小的总和,还有一些其他的东西)。 你的代码就是一个很好的例子:你的typesA是由typesA的大小定义的。

显然,typesA的对象可能不包含也是typesA的成员对象。

你必须存储一个指针或引用; 想要存储也许是可疑的。

你不能在A中包含A.如果你能够这样做,并且你声明了例如A a; ,你需要提到a.member.member.member...无限。 你没有那么多的RAM可用。

class A的实例又如何包含另一个class A实例呢?

它可以持有一个指针,如果你想。

当您尝试使用尚未完全定义的类时,会发生此类错误。

尝试使用A* member

编译器在代码中遇到A的对象时,会发生问题。 编译器会自己动手,并设置一个A的对象。在这样做的时候,它会看到A有一个types为A的成员。因此,为了完成对A的实例化,它现在必须实例化另一个A,这样做必须实例化另一个A等等。 你可以看到它将以没有限制的recursion结束。 因此这是不允许的。 编译器确保在开始实例化一个类的对象之前,它知道所有成员的所有types和内存要求。

理解A类不完整的原因的一个简单方法是从编译器的angular度来看待它。

除此之外,编译器必须能够计算A对象的大小。 知道大小是一个非常基本的要求,在很多情况下都会出现,如在自动内存中分配空间,调用操作符new和评估sizeof(A) 。 然而,计算A的大小需要知道A的大小,因为aA的成员。 这导致无限recursion。

编译器处理这个问题的方法是在完全知道它的定义之前考虑A不完整。 您可以声明指向不完整类的指针和引用,但不允许声明值。