如何通过包含与另一个包含的另一个头文件同名的头文件来创建解决方案?
例如:
// 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
在最后一个头文件中,由于多个包含预处理器保护,因此不会包含a.hpp。真的,这应该没问题,因为类在不同的命名空间中。我意识到,简单的方法是只更改foo / a.hpp的名称,或者只是在多个包含守卫中给它一个假名。还有更好的方法吗?
修改 我知道您可以通过在#define和#ifndef指令中使用更具描述性的名称来解决此问题(例如FOO_A_HPP和BLAH_A_HPP),但我想知道这是推荐的还是最好的方法。有些人会建议使用不同的文件名作为更好的解决方案,还是不重要?你会建议使用这个约定:
<NAMESPACE>_<CLASS>_HPP
而不是
<CLASS>_HPP
通常可以更好地避免这些问题吗?
答案 0 :(得分:8)
你可以通过不在顶部使用相同的#define来解决这个问题......
最好使用BLAH_A_HPP和FOO_A_HPP等,以便#define还包含命名空间名称。
编辑:我个人建议您执行以下操作:
1)不要将标题命名为相同(即使用不同的文件名......这并不总是有帮助)并使用不同的#define名称..
2)不要将类命名为同一个东西。每个标题放1个类,并在类之后命名标题
3)如果它们被命名空间区分,则在文件名中使用该命名空间AND #define
4)添加一个ID给你的#define(我可以使用GOZ)
5)使用#pragma一次。它对编译器很有用。
但这完全是品味问题。选择适合您的方案并坚持下去。没有对错。只要它有效且一致。
答案 1 :(得分:2)
我很惊讶没有人提到使用#undef A_HPP的简单解决方案
//src/foo/c.hpp
#ifndef C_HPP
#define C_HPP
#includes "../b.hpp"
#undef A_HPP
#includes "a.hpp"
...
如果foo / c.hpp是唯一可以或允许更改的文件,这一点特别好。
答案 2 :(得分:1)
当MSVC创建一个类时,它会向你的警卫名称添加一个GUID,以避免出现这种问题。
答案 3 :(得分:0)
虽然C
中没有名称空间,但我认为这适用于C
和C++
。
#ifndef BLAH_B_HPP
和
#ifndef FOO_B_HPP
答案 4 :(得分:0)
正如您自己建议的那样,通常的方法是通过附加GUID或完整路径或者您拥有的内容来使您的保护标识符唯一。
在VC ++中还有一个pragma
来处理多个包含,所以你不需要自己编写#if defined(HUMPTYDUMPTY)
位,就像
#pragma once
现在已经进行了几次VC ++迭代,但对于其他编译器,你需要检查。这也为您节省了寻找唯一名称的麻烦。
编辑:刚看了一眼,互联网认为这也是在GCC。好像#include
风格的守卫是20世纪......