The #include preprocessor directive performs a simple text substitution of the requested header file. Consequently, it is possible for one file being compiled to have multiple copies of of a file.
For example, main.cpp includes both Verbose.h and the iostream.h header file, however, Verbose.h also includes the iostream.h header file.
To prevent duplicate appearances of definitions within a single file being compiled, it is usual practice to wrap the class definition with:
#ifndef SOME_UNIQUE_SYMBOL #define SOME_UNIQUE_SYMBOL // include class definition #endif
The #ifndef conditional test checks "if the symbol SOME_UNIQUE_SYMBOL is not defined.
Thus, the first time that the preprocessor comes across the #ifndef SOME_UNIQUE_SYMBOL directive, the symbol will not be defined, and thus, the body of the directive (up to #endif) will be included in the file sent to the compiler.
If, at any other time, the same header file is included, the symbol SOME_UNIQUE_SYMBOL will be defined and therefore the #ifndef test will fail, hence, the body will not be included as second time.
It is possible to undefine a symbol by using the #undef preprocessor directive.
For example, consider the following code:
#include <iostream> using namespace std; int main() { #ifndef SYMBOL // This first line tells the preprocessor to register SYMBOL as being defined #define SYMBOL cout << "SYMBOL has just been defined" << endl; #endif #ifndef SYMBOL cout << "...this does not print--it does not even reach the compiler..." << endl; This will not even reach the compiler because SYMBOL is defined and therefore the preprocessor will ignore this block... Don't do this in reality... #endif #ifdef SYMBOL cout << "SYMBOL is now defined" << endl; #endif // This next line tells the preprocessor to undefine SYMBOL #undef SYMBOL #ifdef SYMBOL cout << "...this does not print--it does not even reach the compiler..." << endl; This will not reach the compiler for the same reason... SYMBOL is no longer defined and therefore this block will be ignored. #endif #ifndef SYMBOL #define SYMBOL cout << "SYMBOL is no longer defined" << endl; #endif #ifdef SYMBOL cout << "SYMBOL has been defined again" << endl; #endif cout << "Now we're at the end..." << endl; return 0; }
This does compile, despite the existence of the bizarre statements. The output of this program is
SYMBOL has just been defined SYMBOL is now defined SYMBOL is no longer defined SYMBOL has been defined again Now we're at the end...
NOTE: Do not use #ifdef for comments.