2011-02-01 42 views
16

C++如何包含通常命名的警衛?我傾向於看到很多:命名包含警衛

#ifndef FOO_H 
#define FOO_H 

// ... 

#endif 

但是,我不認爲這很直觀。在沒有看到文件名的情況下,很難分辨出FOO_H的名稱和名稱是什麼。

什麼被認爲是最佳實踐?

+2

雖然這個名字可能或多或少直觀的,但事實是,與一些經驗,你停止閱讀這些線路。眼睛和大腦習慣了`#ifdef blahblah ...`,我幾乎沒有真正讀過什麼是檢查,它是一個包括後衛。 – 2011-02-01 20:43:53

+3

對此有點有用的觀點:http://stackoverflow.com/questions/1744144/adding-an-include-guard-breaks-the-build/1744302#1744302 – 2011-02-01 20:48:54

+0

任何做C++開發的人最好習慣於識別標頭守衛很快。它會一直遵循你所看到的標準。 「最佳」練習(在引號中是因爲它是必需的)是將ifndef放在第一位,緊跟在後面的定義,並在文件末尾完成。我建議你儘快認識到這一點。 – 2011-02-01 20:50:56

回答

15

從我自己的經驗來看,約定是在包含它們的頭文件之後命名包含守護程序,但名稱全部用大寫字母表示,而句號用下劃線替換。

所以test.h變成TEST_H

這種現實生活中的例子包括Qt Creator,它在自動生成類頭文件時遵循此慣例。

+4

將FILENAME_H用作包含名稱是很好的,因爲您將所有項目和所有庫的所有文件保存在同一目錄中,而無需任何子目錄,因此您知道它們永遠不會有衝突的文件名... – 2011-02-01 20:57:35

+2

雖然這是常見做法,它可能不夠好,取決於你的店鋪用#defines和其他名稱做什麼。 – 2011-02-01 20:58:02

1

我通常使用類似FOO_H_INCLUDED_的東西。一些(Microsoft)頭文件看起來很像GUID的字符串表示形式,但我從不需要任何相當詳細的內容。

3

FOO_H替換爲FOO_H_INCLUDED它更清晰。

1

通常情況下,人們通過文件名來做到這一點,以便每個文件的代碼只被編譯和添加一次。無論你想要什麼,你都可以做FOO_H,但幾乎所有我編碼或看過的東西都使用了文件名。只要確保它是獨一無二的,因爲你不希望你的FOO_H與其他人的FOO_H發生衝突。

10

直接從google's style guide摘自:

所有的頭文件應該有#定義 守衛防止多包容。 符號名稱的格式應爲 爲< PROJECT> _ < PATH> _ < FILE> _H_。到 保證唯一性,它們應該是 根據項目的 源樹中的完整路徑。例如,文件 富/ src目錄/酒吧/項目foo中 baz.h應具有以下後衛:

#ifndef FOO_BAR_BAZ_H_ 
#define FOO_BAR_BAZ_H_ 
... 
#endif // FOO_BAR_BAZ_H_ 

我在自己的項目中使用這種風格。

+5

雖然一般來說谷歌編碼標準是我見過的最糟糕的一種,但我使用名稱空間作爲前綴。如果在多個命名空間中有相同名稱的東西,這是絕對必要的。 – 2011-02-01 20:48:36

1

我通常看看現在是幾點,只是將其附加到它的末尾,即FOO_H_248,這是一個額外的預防措施,無論如何你永遠不必記住它,所以你不必擔心事實上它是神祕的。

2

正如其他人前面提到的,一個很普通的慣例是使用名字的大寫形式,並通過點替換爲下劃線:foo.h中 - > FOO_H

然而,這會導致名稱衝突與簡單和/或通用名稱。由於這個原因,像在非空的Visual C++項目stdafx.h中自動生成的標題附加一些隨機字符串,如:

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS 
#define FOO_H__NsknZfLkajnTFBpHIhKS 
#endif 

http://www.random.org/strings/是此有用的隨機發生器。

而且,如果該文件是一些子模塊的一部分,或者其內容駐留在一個特定的命名空間,我傾向於將它添加到後衛太:

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 

namespace somecomponent 
{ 
    ... 
} 

#endif 
4

看那個#包括是你的頭的代碼。

如果是這樣的:

#include "mylib/myheader.h" 

mylib/myheader.h已經是唯一的名稱。只是大寫和替換/和。與_

#define MYLIB_MYHEADER_H 

如果你有你的包括相對於包含路徑的同名路徑兩個頭,你已經在該級別的碰撞。

16

我個人遵循Boost的建議。它可能是C++庫中質量最好的C++庫中最大的一個,它們沒有問題。

它是這樣:

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED 

// include/pet/project/file.hpp 
#ifndef PET_PROJECT_FILE_HPP_INCLUDED 

是:

  • 法律(由_[A-Z]注意,開始或含有__不是)
  • 容易產生
  • 保證唯一性(作爲包括後衛)在一個項目中(否則你在同一個地方有兩個文件)
  • 保證不會被用於其他任何(如果你最終另一個宏與INCLUDED你求戰心切)

我讀過有關GUID,但這些看起來很怪異。

而且很明顯,我寧願不是所有的編譯器實現#pragma once(或更好,#pragma multiple和「一次」是默認的行爲...)