为什么我们不能在同一类中声明类的对象?

16
class A
{
  A a;//why can't we do this
};

6
当实例化这样一个类时会发生什么?它会构造一个A,该A会构造另一个A,并且以此类推,直到时间的尽头。所以,是的,一个导致堆栈溢出的构造函数并不是一件好事。噢,对了,这个实例会具有无限大小。 - Etienne de Martel
16
这句话的意思是“乌龟一直往下”,意味着有一个无限递归的结构或无穷尽的层次。 - jason
6个回答

24

因为类会无限增大。

(这是通过语言指定的,指定不能将不完整的类型作为成员,只能将引用或指针作为成员,而且在类定义结束之前,A 是一个不完整的类型。)


12
那又怎样,即使它体积无限大又如何?现在的内存价格很便宜! - James McNellis
2
@James:这让我想起了一个人,他想写一个程序,可以创建长度最多为23个字母的所有可能单词,当我告诉他需要超过一百万TB的硬盘时,他并没有退缩... - EboMike

23
你可以这样做。
class A {
    A* a;
}

因为它不需要知道 A 的大小。


12

我猜你可能是从Java或其他语言过来的?A a会创建一个完整的A类型实例,这个实例中包含了A,而这个A又包含了A,接着又包含了A

你可能正在思考这个:

class A
{
  A *a; // A pointer to A, not a full instance
};

想问一下 *a 的大小? - ajaysinghnegi
1
@AjaySinghNegi sizeof(*a) 是指针的大小,因此根据您的架构,很可能是4或8个字节。 - EboMike

8
A a;//why can't we do this

因为A是一个不完整的类型,因为它还没有被定义,而是在被定义。当编译器在class A中看到A时,需要知道A的完整类型,而由于A是不完整的,它无法确定其大小,也无法确定成员变量a将占用多少空间,因此编译器无法编译它。
但是由于指针的大小对编译器来说是众所周知的,无论它是什么类型的指针。您可以像这样在类中定义一个指针:
class A
{
    A *pA; //okay since sizeof(pA) == sizeof(void*) == well-known to the compiler!
};

Online Demo : http://www.ideone.com/oS5Ir


3
这是您可以拥有指向类A对象的指针的方法,这样在编译时不需要知道类A的大小。
class A {
A* a;
};

3
在C++中: 你不能这样做,因为它会形成递归结构(无限计算对象大小),为了克服这个问题, 使用自引用指针,即具有相同类类型地址的指针。
class A
{
    A* aObj; // Self Referential Pointer
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接