Inclusion guard prevents header files to be included multiple times.
It is a common mistake to include, inadvertently, the same header file in a program multiple times. Suppose Head.h includes Circle.h and TestHead.cpp includes both Head.h and Circle.h, as shown in Listings 9.6 and 9.7.
Listing 9.6 Head.h
1 #include “Circle.h”
2 // Other code in Head.h omitted
Listing 9.7 TestHead.cpp
1 #include “Circle.h”
2 #include “Head.h”
3
4 int main()
5 {
6 // Other code in TestHead.cpp omitted
7 }
If you compile TestHead.cpp, you will get a compile error indicating that there are multiple definitions for Circle. What is wrong here? Recall that the C++ preprocessor inserts the contents of the header file at the position where the header is included. Circle.h is included in line 1. Since the header file for Circle is also included in Head.h (see line 1 in Listing 9.6), the preprocessor will add the definition for the Circle class another time as result of including Head.h in TestHead.cpp, which causes the multiple-inclusion errors.
The C++ #ifndef directive along with the #define directive can be used to prevent a header file from being included multiple times. This is known as inclusion guard. To make this work, you have to add three lines to the header file. The three lines are highlighted in Listing 9.8.
Listing 9.8 CircleWithInclusionGuard.h
1 #ifndef CIRCLE_H
2 #define CIRCLE_H
3
4 class Circle
5 {
6 public:
7 // The radius of this circle
8 double radius;
9
10 // Construct a default circle object
11 Circle();
12
13 // Construct a circle object
14 Circle(double);
15
16 // Return the area of this circle
17 double getArea();
18 };
19
20 #endif
Recall that the statements preceded by the pound sign (#) are preprocessor directives. They are interpreted by the C++ preprocessor. The preprocessor directive #ifndef stands for “if not defined.” Line 1 tests whether the symbol CIRCLE_H is already defined. If not, define the symbol in line 2 using the #defi ne directive and the rest of the header file is included; otherwise, the rest of the header file is skipped. The #endi f directive is needed to indicate the end of header file.
To avoid multiple-inclusion errors, define a class using the following template and convention for naming the symbol:
#ifndef ClassName_H
#define ClassName_H
A class header for the class named ClassName
#endif
If you replace Circle.h by CircleWithInclusionGuard.h in Listings 9.6 and 9.7, the program will not have the multiple-inclusion error.
Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.