我正在尝试定义一个具有该类型元素的类。换句话说:
class Cell {
public:
int row;
int col;
Cell parent;
};
我在 Visual studio 下工作,parent
带有下划线并显示以下错误:不允许使用不完整的类型
。我相信这是因为我引用的是尚未完成声明的内容。所以我尝试通过将其定义为类型来做一些不同的事情:
typedef struct s_cell {
int row;
int col;
struct s_cell parent;
} Cell;
我遇到了同样的问题。我敢肯定这是出于同样的原因。
为了回答您的问题,我们假设这是允许的。 (为了简单起见,也因为这是我更熟悉的,我将使用 C struct
案例作为示例。C++ 案例是相同的,如果您交换关键字而是使用 class
。)
struct
类型的变量与 struct
的所有成员一样大。因此,假设您有以下内容:
struct foo {
int x;
int y;
};
假设 int
是 4 个字节(许多现代平台中的常见假设),struct foo
类型的变量需要 8 个字节(4 的两倍,因为它包含两个int
成员)在内存中并包含两个整数。
现在,让我们这样做:
struct bar {
int a;
int b;
struct bar another; // "bar another;" would be OK in C++, not in C
};
所以一个 struct bar
变量将是……多长?每个 int
有 4 个,所以有 8 个,再加上...它自己的大小,因为它包含一个 copy 自己。所以 sizeof(struct bar) == 8 + sizeof(struct bar)
。这没有意义。 struct
的内容也没有意义 — 它包含两个 int
成员,然后...另一个 struct bar
以及另外两个,其中包含 yet another struct bar
和另外两个,等等 ad infinitum。你最终会遇到无限递归的情况。
在这种情况下,您可能想要做的是有一个指向另一个 struct bar
的指针,它可能为 null,也可能不是 null:
struct bar {
int a;
int b;
struct bar * another;
};
这具有明确定义的内容(两个 int
成员和一个指针成员),具有明确定义的大小(例如,16 字节,假设指针占用 8 个字节)。
回到你的牢房,你会:
class Cell {
public:
int row;
int col;
Cell * parent;
};
现在您有一个指向不完整类型的指针,而不是不完整类型,这是允许的。 (考虑定义为不完整类型的 void
和因此是指向不完整类型的指针的 void *
。您永远不能将前者用作成员的类型,但您始终可以使用后者。)
事实上,至少有一个细胞没有父细胞; 某物 可能是您所有细胞的根和祖先。该单元格将 nullptr
作为 parent
的值。