A header provides a centralized location for related declarations. Headers normally contain class definitions, extern variable declarations, and function declarations, about which we’ll learn in Section 7.4 (p. 251). Files that use or define these entities include the appropriate header(s).
Proper use of header files can provide two benefits: All files are guaranteed to use the same declaration for a given entity; and should a declaration require change, only the header needs to be updated.
Some care should be taken in designing headers. The declarations in a header should logically belong together. A header takes time to compile. If it is too large programmers may be reluctant to incur the compile-time cost of including it.
To reduce the compile time needed to process headers, some C++(www.cppentry.com) implementations support precompiled header files. For more details, consult the reference manual of your C++(www.cppentry.com) implementation.
Headers Are for Declarations, Not Definitions
When designing a header it is essential to remember the difference between definitions, which may only occur once, and declarations, which may occur multiple times (Section 2.3.5, p. 52). The following statements are definitions and therefore
should not appear in a header:
- extern int ival = 10;
- double fica_rate;
Although ival is declared extern, it has an initializer, which means this statement is a definition. Similarly, the declaration of fica_rate, although it does not have an initializer, is a definition because the extern keyword is absent. Including either of these definitions in two or more files of the same program will result in a linker error complaining about multiple definitions.
COMPILING AND LINKING MULTIPLE SOURCE FILES
To produce an executable file, we must tell the compiler not only where to find our main function but also where to find the definition of the member functions defined by the Sales_item class. Let’s assume that we have two files: main.cc, which contains the definition of main, and Sales_item.cc, which contains the Sales_item member functions. We might compile these files as follows:
- $ CC -c main.cc Sales_item.cc # by default generates a.exe
- # some compilers generate a.out
- # puts the executable in main.exe
- $ CC -c main.cc Sales_item.cc -o main
where $ is our system prompt and # begins a command-line comment. We can now run the executable file, which will run our main program.
If we have only changed one of our .cc source files, it is more efficient to recompile only the file that actually changed. Most compilers provide a way to separately compile each file. This process usually yields a .o file, where the .o extension implies that the file contains object code.
The compiler lets us link object files together to form an executable. On the system we use, inwhich the compiler is invoked by a command named CC,we would compile our program as follows:
- $ CC -c main.cc # generates main.o
- $ CC -c Sales_item.cc # generates Sales_item.o
- $ CC main.o Sales_item.o # by default generates a.exe;
- # some compilers generate a.out
- # puts the executable in main.exe
- $ CC main.o Sales_item.o -o main
You’ll need to check with your compiler’s user’s guide to understand how to compile and execute programs made up of multiple source files.
Many compilers offer an option to enhance the error detection of the compiler. Check your compiler’s user’s guide to see what additional checks are available.
Because headers are included in multiple source files, they should not contain definitions of variables or functions.
There are three exceptions to the rule that headers should not contain definitions: classes, const objects whose value is known at compile time, and inline functions (Section 7.6 (p. 256) covers inline functions) are all defined in headers. These entitiesmay be defined in more than one source file as long as the definitions in each file are exactly the same.
These entities are defined in headers because the compiler needs their definitions (not just declarations) to generate code. For example, to generate code that defines or uses objects of a class type, the compiler needs to know what datamembers make up that type. It also needs to know what operations can be performed on these objects. The class definition provides the needed information. That const objects are defined in a header may require a bit more explanation.