类类型的“不允许使用不完整的类型”数组

时间:2018-12-24 18:30:39

标签: c++ arrays

我要在main.cpp之外放置一个类定义和一个void函数,但是在进行运动声明时,它给我“不允许使用不完整的类型”,我该怎么办?

main.cpp:

#include "importer.h"

int main(){
    object sports[200];  //here it give me the error

importer.h:

extern class object;

importer.cpp:

class object {
public:
    string attributes[5];
    string name;
    int objectsLength = 0;
};

2 个答案:

答案 0 :(得分:2)

 extern class object;

首先,这在C ++中是不合法的。如果您没有收到有关此行的任何消息,则说明您的编译器松驰。尝试提高警告级别。

class object;

是正常且合法的。该声明足以定义指向object的指针,但不足以声明类型为object的数组(或单个变量)。

object* ptr;      // good
object  var;      // bad
object  arr[100]; // bad

为了能够使用最后两行,您需要使class object的定义可见。这是因为编译器需要知道每个object的大小,以及如何构造和销毁它们。

从技术上讲,在定义该类型的对象之前,类型必须为 complete

通常,您可以通过将类定义放在头文件中来使其可见。

答案 1 :(得分:1)

我不确定最终目标,因此在这种情况下我看不到使用extern或forward声明的理由。

最常用于声明的类是在必须相互调用(即回调)时使用,因为它们不能包含彼此的头文件。在这种情况下,一个类在另一个头中被向前声明,并且指向该类的指针被声明为成员变量,但是源文件包含必需的头。请注意,即使类本身不是已知的,指针的大小也是已知的。

在这种情况下使用extern的原因是如果 importer 被编译为单独的静态库。   extern ,它将避免优化未使用的类,以便可以从另一个二进制文件链接到该类。

请考虑将main称为 sports [200] 放在堆栈上,此时必须知道 sports 的大小。这不是因为此信息位于main.cpp未知的importer.cpp中。

最简单的解决方案是将定义放在导入程序头文件中,但是我想这是原本没有完成的原因。

我建议避免(如果可能)前向声明,因为这会将编译错误转换为链接器错误,而链接器错误通常更难调试。在大多数情况下,应尽量少使用Extern。