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

时间:2019-03-03 05:32:34

标签: c++ c class typedef incomplete-type

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

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;

我遇到同样的问题。我确定是出于同样的原因。

1 个答案:

答案 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的值。