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

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

我正在尝试定义一个 class,其中包含一个属于该类型的元素。换句话说:

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;

我遇到了同样的问题。我敢肯定这是出于同样的原因。

为了回答您的问题,我们假设这是允许的。 (为了简单起见,也因为这是我更熟悉的,我将使用 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 还有两个,其中包含 另一个 struct bar 还有两个,依此类推 无限 。你最终会遇到无限递归的情况。

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

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.

的值