我是C ++的新手并且有一个问题:
比较以下代码:
class Node {
public:
int data;
Node* x;
};
和
class Node {
public:
int data;
Node x;
};
我知道代码的第二部分无法通过编译。但我想知道原因。
它与内存分配或语法规则有关吗?
如果有人能解决我的问题,我将不胜感激。
答案 0 :(得分:14)
如果可以,则Node
将包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
1}},其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
包含Node
的{{1}},其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
},其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含Node
,其中包含{ Node
,其中包含Node
,其中包含Node
,其中包含Node
输入Nodes
......依此类推,直到宇宙充满{{1}}并发生内爆。
答案 1 :(得分:12)
第二个片段中的代码无法编译,因为类Node
未在声明其x
类型Node
的数据成员时完全定义。
为了理解,想象一下如果它可以编译,它将导致某种“无限递归结构”,这将占用无限量的内存。 这是这种类对象的假设布局:
{
data: int
x: Node
{
data: int
x: Node
{
data: int
x: Node
{
...
}
}
}
}
第一种情况有效,因为您不需要完全定义类来声明指向它的指针 我发现将“完全定义”视为“编译器知道这个类有多大”有助于解释这样的问题:编译器需要知道一个类声明它的实例有多大,但不要声明一个指向它的指针,无论类如何都具有相同的大小。
答案 2 :(得分:7)
它与基本逻辑更相关。为了使Node
包含与其自身大小相同的对象,以及其他内容,它必须比自身大,或者大小无限。
语言也会阻止它,因为类型在其自己的定义中是不完整的(所以你甚至不能拥有包含自身的其他空类的退化情况)。但这相当于更基本的逻辑不可能性。
答案 3 :(得分:0)
编译器在A类中发现它时需要知道A的完整类型。因为A不完整,无法确定其大小,无法确定成员变量a将占用多少空间,因此它将不编译它。
答案 4 :(得分:-2)
要解决此类问题,您还可以尝试前瞻性声明。 但问题出在Martin J已经说过的话。
class Node;
class Node {
public:
int data;
Node* x;
};
请记住,这未经过测试