This question already has an answer here:
-
Can a c++ class include itself as an member?
4 answers
I am new to C++ and have a question:
Compare following code:
class Node {
public:
int data;
Node* x;
};
and
class Node {
public:
int data;
Node x;
};
I know the second part of code can't pass compile. But I want to know the reason.
Is it related to memory allocation or just syntax regulation?
I would be appreciate if someone can solve my question.
The code in your second fragment cannot compile, because the class Node
is not completely defined at the point where you declare its data member x
of Node
type.
For the sake of understanding, imagine if it could compile, it would lead to some sort of "infinite recursion structure", that would take an infinite amount of memory.
Here's the hypothetical layout of such a class object:
{
data: int
x: Node
{
data: int
x: Node
{
data: int
x: Node
{
...
}
}
}
}
The first case works because you do not need a class to be fully defined in order to declare a pointer to it.
I find that thinking of "fully defined" as "the compiler knows how big this class is" helps to reason about problems like this: the compiler needs to know how big a class is to declare an instance of it, but not to declare a pointer to it, which has the same size regardless of the class.
If you could, then a Node
would contain a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
, which contains a Node
... and so on until the universe is full of Nodes
and implodes.
It's more related to basic logic. In order for Node
to contain an object of the same size as itself, and something else, it would have to be larger than itself, or infinite in size.
The language also prevents it since the type is incomplete within its own definition (so you can't even have the degenerate case of an otherwise empty class containing itself). But that's rather incidental to the more fundamental logical impossibility.
The compiler needs to know the complete type of A when it founds it inside class A. Because A is incomplete, it cannot determine its size, it cannot determine how much space the member variable a is going to take, therefore it will not compile it.
To fix such a problem you could also give forward declaration a try.
But the problem lies in what Martin J Already stated.
class Node;
class Node {
public:
int data;
Node* x;
};
bear in mind this is not tested