Objects and Classes in C++: Preventing Multiple Inclusions

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 multi­ple 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 multi­ple 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 includ­ing 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 conven­tion 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.

Leave a Reply

Your email address will not be published. Required fields are marked *