2013-05-17 36 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