4.7.2 多次声明问题

头文件的第二个问题是:如果把一个struct声明放在一个头文件中,就有可能在一个编译程序中多次包含这个头文件。输入输出流就是一个很好的例子。每次一个struct做I/O都可能包含一个输入输出流文件。如果我们正在开发的cpp文件使用多种struct(典型的是每种包含一个头文件),这样就有多次包含<iostream>和重声明输入输出流的危险。

编译器认为重声明结构(包括struct和class)是一个错误,因为它还允许对不同的类型使用相同的名字。为了防止多次头文件包含引起的错误,需要在头文件中用预处理器建立一些智能功能(标准C++头文件中<iostream>等已经具有这样的“智能”)。

C和C++都允许重声明函数,只要两个声明匹配即可,但是两者都不允许重声明结构。在C++中,这条规则是特别重要的,因为如果编译器允许重声明一个结构而且这两个声明不同,那么应当使用哪一个声明呢?

重声明在C++中出现了问题,因为每个数据类型(带函数的结构)一般有它自己的头文件,如果想创造另一个数据类型(它使用第一个数据类型),则我们必须将第一个数据类型的头文件包含在这另一个数据类型中。在我们项目的任何cpp文件中,很可能包含几个已经包含了这个相同的头文件的文件。在一次编译过程中,编译器可能会多次看到这个相同的头文件。除非特别处理,否则编译器将发现结构的重声明,并报告编译时错误。为了解决这个问题,需要知道更多的预处理器的知识。