Q: What is the purpose of include guards?
Q: Why do I get the compiler error "xxx already defined" when I include my own files?
A: In order to understand the solution, we must first understand the mechanism of how include files work. When you put a line
in another file, then during compilation the contents of the file called 'myheader.h' will be inserted at that location. This is a simple concept but can lead to problems.Code:#include "myheader.h"
One such problematic case is when you have three header files. Let's call them 'header_base', 'header_a' and 'header_b'. Both 'header_a' and 'header_b' include 'header_base', because they need the definitions found there. When you now include 'header_a' and 'header_b' inside a '.cpp' file, you'll most likely get a compiler error complaing about multiple definitions.
The offending code could be structered like this:
When 'main.cpp' gets compiled, the contents of the header will be inserted at the appropriate locations and this will result in the following code:Code:// header_base.h class base_class { // some code }; // header_a.h #include "header_base.h" class derived_a : public base_class { // some code }; // header_b.h #include "header_base.h" class derived_b : public base_class { // some code }; // main.cpp #include "header_a.h" #include "header_b.h" int main() { return 0; }
Now it's pretty clear that 'base_class' is defined twice and this is not legal C++. The solution is to make use of a preprocessor definition specific to the header file which guards its contents from being dumped twice into the same cpp file. An example is the following.Code:// #include "header_a.h" // code for header_a.h begins // #include "header_base.h" // code for header_base.h begins class base_class { // some code }; // code for header_base.h ends class derived_a : public base_class { // some code }; // code for header_a.h ends // #include "header_b.h" // code for header_b.h begins // #include "header_base.h" // code for header_base.h begins class base_class { // some code }; // code for header_base.h ends class derived_b : public base_class { // some code }; // code for header_b.h ends int main() { return 0; }
The first line checks whether we have not yet defined 'HEADER_BASE_HPP'. If we have not, then we define it and include the rest of the file. If it is already defined, i.e. if this header file has already been included, then we will just skip until the end of the file and nothing more will get dumped into the '.cpp' file.Code:#ifndef HEADER_BASE_HPP #define HEADER_BASE_HPP class base_class { // some code }; #endif // HEADER_BASE_HPP


Reply With Quote
Marius Bancila
Bookmarks