Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: include multiple header files with same name from different namespaces

How do you solve created by including a header file with the same name as another header file already indirectly included as a result of another include?

For instance:

// src/blah/a.hpp
#ifndef A_HPP
#define A_HPP

namspace blah
{

class A
{
}

}

#endif

// src/blah/b.hpp
#ifndef B_HPP
#define B_HPP

#includes "a.hpp"

namspace blah
{

class B
{
}

}

#endif

// src/foo/a.hpp
#ifndef A_HPP
#define A_HPP

namspace foo
{

class A
{
}

}

#endif

// src/foo/c.hpp
#ifndef C_HPP
#define C_HPP

#includes "../b.hpp"
#includes "a.hpp"       // won't be included due to multiple inclusion prevention

namspace foo
{

class C
{
}

}

#endif

In the last header file, a.hpp won't be included because of the multiple inclusion preprocessor guards. Really, this should be okay though since the classes are in different namespaces. I realize that the easy way is to just change the name of foo/a.hpp or to just give it a fake name in the multiple inclusion guard. Is there a better way?

EDIT I understand that you can solve this problem by using a more descriptive name in the #define and #ifndef directives (e.g. FOO_A_HPP and BLAH_A_HPP), but I want to know if that is the recommended or best way. Would some people recommend using a different file name as a better solution or does it not really matter? Would you recommend using the convention:

<NAMESPACE>_<CLASS>_HPP

instead of

<CLASS>_HPP

to give a better chance of avoiding these problems in general?

like image 813
deuberger Avatar asked Sep 10 '10 20:09

deuberger


People also ask

Can I include system headers in a file?

You can include system headers such as <stdio.h> without having to worry about whether there are other headers needed to make use of its services. You should design your own headers in the same way. You should also prevent errors if your file is included multiple times (whether accidentally or deliberately).

How to add a header file in CPP?

Adding a Header File works the same as how we added another CPP source file (Square.cpp) NOTE: Use a .h suffix when naming your header files. Create a new item. By right clicking Project in solution explorer then click Add and in next option menu click on new item. This time select Header File (.h) File.

How to merge existing header files into one?

So you could merge the existing header files into one, and call it node.h. As Joop Eggen recommends, put #ifndef _NODE_H_ ... #endif around node.h contents to protect it against accidentally being #included twice.

What should the base name of a header file be?

NOTE: If a header file is paired with a code file (e.g. Square.h with Square.cpp), they should both have the same base name (Square). Also, Check in Solution explorer if it is added to your solution


2 Answers

You solve this, simply, by not using the same #define at the top ...

It would be better to use BLAH_A_HPP and FOO_A_HPP etc so that the #define also includes the namespace name.

Edit: Well personally I recommend doing the following:

1) Don't name headers the same (ie use different file name ... this doesn't always help) and use different #define names..
2) Don't name classes the same thing. Put 1 class per header and name the header after the class
3) If they are differentiated by a namespace use that namespace in the file name AND #define
4) Add an ID to you #define that is unique to you (I could use GOZ for example)
5) Make use of #pragma once. Its useful for the compilers that ise it.

Its all a matter of taste though. Choose a scheme that works for you and stick with it. There is no right or wrong. As long as it works and is consistent.

like image 88
Goz Avatar answered Oct 01 '22 23:10

Goz


I am surprised that no-one mentioned the simple solution of using #undef A_HPP as below

//src/foo/c.hpp
#ifndef C_HPP
#define C_HPP

#includes "../b.hpp"
#undef A_HPP
#includes "a.hpp" 
...

This is particularly good if foo/c.hpp is the only file one can or is allowed to change.

like image 45
onlooker Avatar answered Oct 02 '22 01:10

onlooker