25

C++ インクルード ガードは通常どのように命名されますか? 私はこれをよく見る傾向があります:

#ifndef FOO_H
#define FOO_H

// ...

#endif

しかし、それはあまり直感的ではないと思います。ファイル名を見ないと、何のFOO_Hためにそこにあり、その名前が何を指しているのかを判断するのは困難です。

ベストプラクティスと見なされるものは何ですか?

4

9 に答える 9

27

私は個人的に Boost の推奨に従っています。これはおそらく、高品質の C++ ライブラリの最大のコレクションの 1 つであり、問​​題はありません。

次のようになります。

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

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

つまり:

  • _[A-Z]合法 (で始まるまたは含むではないことに注意してください__)
  • 生成しやすい
  • プロジェクト内で(インクルードガードとして)一意であることが保証されています(そうでない場合、同じ場所に2つのファイルがあります)
  • 他の目的で使用されないことが保証されています (別のマクロを終了INCLUDEDして、戦いを台無しにしている場合)

GUID について読んだことがありますが、奇妙に見えます。

そして明らかに、私はすべてのコンパイラが実装するよりもむしろ#pragma once(またはより良い、#pragma multipleそして「一度」がデフォルトの動作です...)

于 2011-02-02T07:53:22.173 に答える
22

私自身の経験から、名前がすべて大文字で、ピリオドがアンダースコアに置き換えられていることを除いて、インクルージョンガードにそれらを含むヘッダーファイルにちなんで名前を付けるのが慣例です。

だからtest.hになりTEST_Hます。

この実際の例には、クラスヘッダーファイルを自動生成するときにこの規則に従うQtCreatorが含まれます。

于 2011-02-01T20:28:08.070 に答える
15

Google のスタイル ガイドから直接取得:

複数のインクルードを防ぐために、すべてのヘッダー ファイルに #define ガードを設定する必要があります。シンボル名の形式は、<PROJECT>_<PATH>_<FILE>_H_ である必要があります。一意性を保証するには、プロジェクトのソース ツリーのフル パスに基づく必要があります。たとえば、プロジェクト foo のファイル foo/src/bar/baz.h には、次のガードが必要です。

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

私は自分のプロジェクトでこのスタイルを使用しています。

于 2011-02-01T20:34:32.330 に答える
5

#include がヘッダーのコードを見てください。

次のような場合:

#include "mylib/myheader.h"

mylib/myheader.hはすでに固有の名前です。/ と を大文字にして置き換えるだけです。と _

#define MYLIB_MYHEADER_H

インクルード パスに相対する同じ名前の 2 つのヘッダーがインクルード パスにある場合、そのレベルで既に競合が発生しています。

于 2011-02-01T23:00:39.543 に答える
4

に置き換えるFOO_HFOO_H_INCLUDED、より明確になります。

于 2011-02-01T20:27:03.757 に答える
2

他の人が前に述べたように、非常に一般的な規則は、名前の大文字バージョンを使用し、ドットをアンダースコアに置き換えることです:foo.h-> FOO_H

ただし、これにより、単純な名前や一般的な名前との名前の衝突が発生する可能性があります。このため、空でないVisual C C ++プロジェクトのstdafx.hのような自動生成されたヘッダーは、次のようなランダムな文字列を追加します。

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS
#define FOO_H__NsknZfLkajnTFBpHIhKS
#endif

http://www.random.org/strings/は、このための便利なランダムジェネレーターです。

また、ファイルがサブモジュールの一部である場合、またはその内容が1つの特定の名前空間にある場合は、それをガードにも追加する傾向があります。

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS

namespace somecomponent
{
  ...
}

#endif
于 2011-02-01T21:06:11.200 に答える
1

私は通常、のようなものを使用しますFOO_H_INCLUDED_。いくつかの(Microsoft)ヘッダーには、GUIDの文字列表現によく似たものがありますが、これほど複雑なものは必要ありませんでした。

于 2011-02-01T20:27:01.553 に答える
1

通常、人々はファイル名でそれを行い、各ファイルのコードがコンパイルされて追加されるのは1回だけです。FOO_Hは好きなように作成できますが、私がこれまでにコーディングまたは表示したほとんどすべてのものでファイル名が使用されています。FOO_Hが他の人のFOO_Hと競合しないようにするため、一意であることを確認してください。

于 2011-02-01T20:28:23.207 に答える
1

私は通常、今何時かを見て、それを末尾に追加します。つまりFOO_H_248、これは特別な予防措置であり、とにかく覚える必要がないため、暗号化されているという事実について心配する必要はありません。

于 2011-02-01T20:48:41.637 に答える