我在尝试使用没有初始大小的结构数组时遇到问题。我该怎么做?这是我的结构:
struct carbon {
double temp;
double mass;
rowvec::fixed<3> position;
rowvec::fixed<3> velocity;
rowvec::fixed<3> force;
} *atom;
在我的程序中,我分配结构数组的大小,如下所示:
atom = new carbon[PARTICLE_NUM];
问题是我如何在其他文件中使用这个结构。我创建了一个头文件并将其放入
extern struct carbon *atom;
但它出现了一个错误:
setup_pos.cpp:19: error: invalid use of incomplete type ‘struct carbon’
system_setup_distances.h:18: error: forward declaration of ‘struct carbon’
我知道我不应该使用全局变量,但我只想先测试一下。提前感谢您的帮助。
使用atom
的源文件需要carbon
结构的完整定义。
将结构与外部放在同一个头文件中,如下所示:
struct carbon {
double temp;
double mass;
rowvec::fixed<3> position;
rowvec::fixed<3> velocity;
rowvec::fixed<3> force;
};
extern struct carbon *atom;
在一个源文件中定义变量atom
:
struct carbon *atom = 0;
现在,无论何时需要访问atom
,都要包括结构和外部声明所在的头文件,它应该可以工作。
PS。您可以将atom
变量放在自己的命名空间中,而不是放在全局命名空间中:
namespace some_clever_name
{
struct carbon { ... };
extern carbon *atom;
}
并将其放入源文件:
some_clever_name::carbon *some_clever_name::atom = 0;
结构的定义需要在头文件中。
您需要将结构carbon
的定义包含在头文件中,然后将该头文件包含在文件(.h
或.cpp
)中,在这些文件中您将获得不完整的类型错误。
为什么出现错误
无论何时使用前向声明,该类型都会成为编译器的不完整类型,这是因为编译器只知道前向声明的实体是数据类型,但对布局或其内部一无所知,因此,如果执行任何需要编译器使用类型布局的操作,它会报告错误。
在您的情况下,编译器需要知道结构carbon
的大小才能分配足够的内存,但它不能这样做,因为它是前向声明的类型,因此它会报告错误。
正如其他答案所说,您需要在头文件中包含结构的定义。但让我们问问自己为什么你需要这个?
C++从一开始就以C为基础,并从C继承了一种简单的编译策略:编译器只需一次通过,编译器和链接器都不需要访问它们所呈现的文件之外的任何内容。当C和UNIX刚开发出来的时候,地址空间有限,处理器的速度比大多数人想象的要慢——我的Kindle Fire比我90年代以前使用的任何电脑都要大。
因为他们让编译器变得简单,而不是像PL/I(C的祖先之一)那样使用更复杂的方案,他们构建了预处理器并使用了include文件。编译器需要知道结构的"形状",这样它才能生成代码——例如,如果你想访问mass
,你需要知道结构开头的偏移量。因此,在C和C++中,你需要从文本上包括对"形状"的描述。