2013-05-17 34 views
1

我明白什么是标题守卫,但我从来没有看到它是如何用于更大的项目。我目前正在编写一个OpenGL抽象层,我大多需要包含相同的文件。更大的项目的标题守卫

所以我的第一个幼稚的做法是做这样的事情:

#ifndef GUARD_H 
#define GUARD_H 

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 

#include <GL/glfw3.h> 

#include <glload/gl_core.h> 
#include <glload/gll.h> 

#endif // GUARD_H 

这样我就可以做#include "guard.h"。但是我意识到这不是一个很好的解决方案,因为如果我想添加一个简单的包含函数呢?

是的我可能可以将我的所有包括在这个文件中,但我也不确定这是否是一个好主意。

你怎么会推荐我来构造我的头警卫?你能推荐我任何资源吗?

更新1:小例子

test.h 

     #ifndef TEST_H 
     #define TEST_H 

     #include <glm/glm.hpp> 
     class test{ 
     }; 

     #endif 

test1.h 
      #ifndef TEST1_H 
      #define TEST1_H 

      #include <glm/glm.hpp> 
      class test1{ 
      }; 

     #endif 

现在我包括在我的测试类GLM。但是如果我想要做这样的事情怎么办?

#include "test.h" 
#include "test1.h" 
int main(){ 
//... 
} 

不要包括#include <glm/glm.hpp> 2次在main?

回答

6

这不是把所有包含一个文件,除非你总是包括所有这些文件是一个好主意。

您应该只在您自己的标题中包含严格的所需的标题,并将其余的直接包含在您的.cpp源文件中。

你的每个头文件应该有一个独特的头文件保护而不会与任何其他库冲突,所以要非常注意命名方案。

如果您没有编写可移植代码,您也可以考虑使用非标准指令。

你可以看看this paper about the best practice for designing header files

为了回答您的编辑:

不,你不包括<glm/glm.hpp>两次,因为它本身就是一个头文件保护。但是,只有当您的头部内部需要实际上需要glm.hpp时,您才应该包含它,否则您应该稍后将其包含。请注意,您通常可以避免包含forward-declaring所需的内容,这可以加快编译速度并避免循环依赖,但这是另一个问题。

+0

谢谢我会看看这篇论文。我还用一个例子更新了我的第一篇文章。 –

3

简单。每个标题的标头警卫

你做这件事的方式是不安全的:如果有一天某人(不一定是你,虽然这是不确定的)直接包含你列出的头文件之一(虽然这些头文件看起来大多是外部库文件,但它可能会演变成包括你的一个......),而这个头部没有包含警卫?不妨尽早排除这个可能的问题!

组织你的头,你应该更喜欢包括被严格需要,而不是在一个全局头的一切。

编辑答案:不,你将不包括它的两倍。在第一次包含之后,标题保护文件的每一次额外事件都将被忽略。

+2

甚至更​​简单:在每个头的开头使用'#pragma once'。大多数编译器都支持它,它避免了名称冲突。 – stefan

+0

@stefan我不是一个建议#pragma的粉丝,尽管你说得对,它可以在大多数情况下工作。 – JBL