假设在a.h文件中定义了一个结构体,然后在b.cpp中预先声明这个类型而又不引用头文件a.h,那么这个结构体可以使用吗?看看下面的例子:
编译这个程序,GCC显示错误:field `b' has incomplete type
稍稍修改一下这个文件:
编译通过。
为什么会这样呢?C/C++采用静态的编译模型,程序运行时结构大小都会在编译后确定。程序要正确编译,编译器必须知道一个结构所占用的空间大小。在第一个例子中,结构体bb作为结构体aa的一个成员,要确定aa的大小,必须知道bb的大小,而bb的定义文件没有包含进来,必然编译不能通过。而第二个例子中,指针的大小与机器的字长有关,不管类型是什么类型,编译后指针的大小总是确定的。所以这种情况下不需要知道结构bb的确切定义。
“编译器一定要知道类型的大小”,这条信息可以帮助我们在发生编译错误的时候,更快找到错误的原因。同时,如果我们需要引入的类型仅仅只是声明成指针,则这个类型的头文件不必引入,从而这个文件的编译速度得到了提高。
struct
bb;
//
声明存在的一个类型
struct aa
{
bb b;
};
struct aa
{
bb b;
};
编译这个程序,GCC显示错误:field `b' has incomplete type
稍稍修改一下这个文件:
struct
bb;
//
声明存在的一个类型
struct aa
{
bb * b;
};
struct aa
{
bb * b;
};
为什么会这样呢?C/C++采用静态的编译模型,程序运行时结构大小都会在编译后确定。程序要正确编译,编译器必须知道一个结构所占用的空间大小。在第一个例子中,结构体bb作为结构体aa的一个成员,要确定aa的大小,必须知道bb的大小,而bb的定义文件没有包含进来,必然编译不能通过。而第二个例子中,指针的大小与机器的字长有关,不管类型是什么类型,编译后指针的大小总是确定的。所以这种情况下不需要知道结构bb的确切定义。
“编译器一定要知道类型的大小”,这条信息可以帮助我们在发生编译错误的时候,更快找到错误的原因。同时,如果我们需要引入的类型仅仅只是声明成指针,则这个类型的头文件不必引入,从而这个文件的编译速度得到了提高。