C ++ - 声明struct和class [duplicate]时不允许使用不完整类型

问题描述 投票:0回答:1

这个问题在这里已有答案:

我试图定义一个具有该类型元素的类。把它说成更好的词:

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++ c class typedef incomplete-type
1个回答
5
投票

要回答你的问题,让我们假装这是允许的。 (为了简单起见,因为它是我更熟悉的,我将使用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,加上...自己的大小,因为它包含自己的副本。所以sizeof(struct bar) == 8 + sizeof(struct bar)。这没有意义。 struct的内容也没有意义 - 它包含两个int成员,然后......另外两个struct bar,其中包含另外两个struct bar,还有两个以上,等等无限广告。你最终得到了一个无限递归的例子。

在这种情况下你可能想做的是有一个指向另一个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的值。

© www.soinside.com 2019 - 2024. All rights reserved.