我正在尝试定义一个具有该类型元素的类。用更好的话来说:
class Cell {
public:
int row;
int col;
Cell parent;
};
我在Visual Studio下工作,parent
的下划线带有错误:incomplete type is not allowed
。我相信这是因为我引用的是尚未完成声明的内容。因此,我尝试通过将其定义为类型来做一些不同的事情:
typedef struct s_cell {
int row;
int col;
struct s_cell parent;
} Cell;
我遇到同样的问题。我确定是出于同样的原因。
答案 0 :(得分:5)
为回答您的问题,让我们假装这是允许的。 (为简单起见,并且因为这是我更熟悉的示例,所以我将使用C struct
案例作为示例。C++案例是相同的,如果您使用的是关键字交换改为class
。
struct
类型的变量与struct
的所有成员一样大。因此,假设您具有以下条件:
struct foo {
int x;
int y;
};
假设int
是4个字节(在许多现代平台中是一个常见的假设),类型struct foo
的变量将占用8个字节(两次,因为它包含两个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个,加上它自己的大小,因为它包含自身的副本。 sizeof(struct bar) == 8 + sizeof(struct bar)
这样。这没有道理。 struct
的内容也没有意义-它包含两个int
成员,然后...另一个struct bar
和另外两个成员,其中还有另一个 struct bar
和另外两个,依此类推,依次为 ad infinitum 。您最终将遇到无限递归的情况。
在这种情况下,您可能想做的是指向另一个struct bar
的 pointer 指针,该指针可以为null或不为null:
struct bar {
int a;
int b;
struct bar * another;
};
这具有定义明确的内容(两个int
成员和一个指针成员),并且具有明确定义的大小(例如,假设指针占用8个字节,则为16个字节)。
回到您的手机,您将拥有:
class Cell {
public:
int row;
int col;
Cell * parent;
};
现在,您可以使用指向不完整类型的指针,而不是不完整类型。 (请考虑将void
定义为不完整类型,而将void *
定义为不完整类型的指针。您永远不能将前者用作成员的类型,但始终可以使用后者。
实际上,您的至少一个单元将没有父级; 某物可能是您所有细胞的根源和祖先。该单元格将以nullptr
作为parent
的值。