繁体   English   中英

为什么编译器在此代码中说“不完整类型错误”?

[英]why compiler is saying Incomplete type error in this code?

#include<iostream.h>

class A 
{    
   A a;            

};             

int main()       
{       

A a;              
return 0;           
}

为什么编译器说“ a”具有不完整的类型? 但是在Java中会发生递归..plz解释。

在C ++中, A a表示类型A的对象,而不是指向位于其他位置的某个对象的引用或指针。 必须知道A的定义才能做出这样的陈述,除其他外,这意味着必须完全确定A的大小。

当您尝试将某个类型的实例作为同一类型的成员时,您将获得无限递归。 该语言只是禁止这样做,指出任何类型的数据成员都必须是完整类型 ,这意味着其定义必须可用。

另一方面,这是允许的,并且更接近于Java语义:

class A { A* a; };
class B { B& b; };

有关更多信息,请参见此相关文章: 何时使用前向声明?

两者不相等。 在Java中命名对象时,实际上是在命名引用,因此C ++中的等效代码为:

class A 
{    
   A& a;
};

或者,可以说:

class A 
{    
   A* a;
};

这些都是完全有效的。

另一方面,尝试存储类型A显然是行不通的。 Java根本没有语法甚至可以尝试这样做,但是C ++确实有-且不完整的类型规则会阻止您陷入其中。

在C ++中,您需要一个与该类处于同一类型的成员。这是不允许的,因为您需要知道对象的大小才能创建分配它的内存布局,并且它可能会如下所示:

- what's the size of A?
  - it contains an object of class A.. what's the size of this object?
    - what's the size of A?
      - it contains.. bla bla bla

并且您最终将获得无限的递归而没有任何意义。 那是不允许的。 您可以使用引用或指针解决问题,但这与您要求的解决方案不同。

在Java中,允许使用语法,因为它不实例化类型(它是一个引用 ),但是如果您尝试实例化,则行为是相同的

public class myClass {
   private myClass p = new myClass(); // Runtime error!!

   public static void main(String[] args) {
      new myClass();
   }
}

需要注意的一件事:Java不会在编译时捕获它,而只会在运行时捕获(因此耗尽VM的内存,除非在此之前未检测到该机制),而C ++设法在编译时捕获它。

如果我们使用C ++标准草案,则可以看到直到结束}才完全定义一个类,这在9.2 类成员2段中:

在classspecifier的结尾},类被视为完全定义的对象类型(3.9)(或完整类型)。 [...]

并且一个类的所有非静态数据成员必须完整,这在第9段中:

非静态(9.4)数据成员不应具有不完整的类型。 特别地,类C不应包含类C的非静态成员,但可以包含对类C的对象的指针或引用。

但是正如它所说的,它可以包含一个指针或一个引用,它与Java的实现方式更为接近。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM