C++如何包含通常命名的警衛?我傾向於看到很多:命名包含警衛
#ifndef FOO_H
#define FOO_H
// ...
#endif
但是,我不認爲這很直觀。在沒有看到文件名的情況下,很難分辨出FOO_H
的名稱和名稱是什麼。
什麼被認爲是最佳實踐?
C++如何包含通常命名的警衛?我傾向於看到很多:命名包含警衛
#ifndef FOO_H
#define FOO_H
// ...
#endif
但是,我不認爲這很直觀。在沒有看到文件名的情況下,很難分辨出FOO_H
的名稱和名稱是什麼。
什麼被認爲是最佳實踐?
從我自己的經驗來看,約定是在包含它們的頭文件之後命名包含守護程序,但名稱全部用大寫字母表示,而句號用下劃線替換。
所以test.h
變成TEST_H
。
這種現實生活中的例子包括Qt Creator,它在自動生成類頭文件時遵循此慣例。
將FILENAME_H用作包含名稱是很好的,因爲您將所有項目和所有庫的所有文件保存在同一目錄中,而無需任何子目錄,因此您知道它們永遠不會有衝突的文件名... – 2011-02-01 20:57:35
雖然這是常見做法,它可能不夠好,取決於你的店鋪用#defines和其他名稱做什麼。 – 2011-02-01 20:58:02
我通常使用類似FOO_H_INCLUDED_
的東西。一些(Microsoft)頭文件看起來很像GUID的字符串表示形式,但我從不需要任何相當詳細的內容。
將FOO_H
替換爲FOO_H_INCLUDED
它更清晰。
通常情況下,人們通過文件名來做到這一點,以便每個文件的代碼只被編譯和添加一次。無論你想要什麼,你都可以做FOO_H,但幾乎所有我編碼或看過的東西都使用了文件名。只要確保它是獨一無二的,因爲你不希望你的FOO_H與其他人的FOO_H發生衝突。
直接從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_
我在自己的項目中使用這種風格。
雖然一般來說谷歌編碼標準是我見過的最糟糕的一種,但我使用名稱空間作爲前綴。如果在多個命名空間中有相同名稱的東西,這是絕對必要的。 – 2011-02-01 20:48:36
我通常看看現在是幾點,只是將其附加到它的末尾,即FOO_H_248
,這是一個額外的預防措施,無論如何你永遠不必記住它,所以你不必擔心事實上它是神祕的。
正如其他人前面提到的,一個很普通的慣例是使用名字的大寫形式,並通過點替換爲下劃線: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
看那個#包括是你的頭的代碼。
如果是這樣的:
#include "mylib/myheader.h"
mylib/myheader.h
已經是唯一的名稱。只是大寫和替換/和。與_
#define MYLIB_MYHEADER_H
如果你有你的包括相對於包含路徑的同名路徑兩個頭,你已經在該級別的碰撞。
我個人遵循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
和「一次」是默認的行爲...)
雖然這個名字可能或多或少直觀的,但事實是,與一些經驗,你停止閱讀這些線路。眼睛和大腦習慣了`#ifdef blahblah ...`,我幾乎沒有真正讀過什麼是檢查,它是一個包括後衛。 – 2011-02-01 20:43:53
對此有點有用的觀點:http://stackoverflow.com/questions/1744144/adding-an-include-guard-breaks-the-build/1744302#1744302 – 2011-02-01 20:48:54
任何做C++開發的人最好習慣於識別標頭守衛很快。它會一直遵循你所看到的標準。 「最佳」練習(在引號中是因爲它是必需的)是將ifndef放在第一位,緊跟在後面的定義,並在文件末尾完成。我建議你儘快認識到這一點。 – 2011-02-01 20:50:56