C++ - 声明结构和类时不允许使用不完整的类型

C++ - Incomplete type not allowed while declaring struct and class

本文关键字:用不完 类型 不允许 声明 结构 C++      更新时间:2023-10-16

我正在尝试定义一个具有该类型元素的类。 用更好的词来说:

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;

我得到同样的问题。我敢肯定也是出于同样的原因。

为了回答你的问题,让我们假装这是允许的。(为了简单起见,并且因为它是我更熟悉的,我将使用 Cstruct案例作为示例。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 个,加上...它自己的大小,因为它包含自己的副本。所以sizeof(struct bar) == 8 + sizeof(struct bar).这说不通。struct的内容也没有意义——它包含两个int成员,然后......另一个struct bar还有两个,其中包含另一个struct bar,还有两个,依此类推无穷无尽。你最终会得到无限递归的情况。

在这种情况下,您可能想要做的是有一个指向另一个struct bar的指针,该指针可能是也可能不是空的:

struct bar {
int a;
int b;
struct bar * another;
};

它具有明确定义的内容(两个int成员和一个指针成员),具有明确定义的大小(例如,假设指针占用 8 个字节,则为 16 个字节)。

回到您的牢房,您将拥有:

class Cell {
public:
int row;
int col;
Cell * parent;
};

现在,您有一个指向不完整类型的指针,而不是不完整的类型,这是允许的。(考虑定义为不完整类型的voidvoid *,因此它是指向不完整类型的指针。您永远不能将前者用作成员的类型,但始终可以使用后者。

事实上,您的至少一个细胞将没有父细胞;有些东西可能是你所有细胞的根源和祖先。该单元格将具有nullptr作为parent的值。