web-dev-qa-db-ja.com

標準ライブラリヘッダーを複数のプログラムヘッダーに1回だけ含める

次のように、複数のヘッダーとコードファイルを含むプログラムを作成しています。

  • message.h
  • message.cpp
  • option.h
  • option.cpp
  • main.cpp

message.cppはそこで定義されたクラスの定義を必要とするため、message.hにはoption.hが含まれています。

他にもかなりの数のファイルがありますが、簡潔にするために...
memcpyなどの関数を呼び出す場合は、string.hを含めます。 string.hをmessage.hに含めます-したがって、message.cppで正常に動作しますが、option.cppで使用したい場合、エラーが発生します。

だから私は2つのオプションを見ます:

  1. Option.hには、message.hを再度含めます。両方のヘッダーファイルにガードが含まれているため、これは問題にはなりませんが、かなり面倒です。
  2. Option.hにstring.hを含めます。ここで、両方のヘッダーファイルにstring.hを含めます。

これでmemcpyの宣言ができるので、プログラミングを続行できます。ただし、多くの異なる機能に10の異なるヘッダーを含めると、再び厄介になります。

この問題を回避するためにコードを構造化し、コードを可能な限り整頓するための良い方法は何ですか?すべてのインクルードを1つの別個のファイルにして、すべてのヘッダーファイルにインクルードすることは私の心を超えました。これは将来の問題になる可能性があります。コードを保守可能にするためにこれに対処できるより良い方法はありますか?

3
Shane

対応する.hに含まれていない.cppファイルに追加のヘッダーを#includeしても問題ありません。実際、.hでヘッダーが不要な場合は、常にそうする必要があります。これにより、.cppではなく.hに依存するもののコンパイルが高速化される可能性があります。ヘッダーファイル内の不要な#includeを最小限に抑えるためのいくつかのヒントについては、 この古典的な今週の第一人者 を参照してください(まだ古くなっていないと思います)。

一般に、コードをよりモジュール化する(そして他の標準ライブラリに移植しやすくする)ため、他のファイルの機能に依存することはできるだけ避けます。つまり、すべてのファイルが明示的かつ直接#それが知る必要があるすべてのヘッダーを含める必要があります(私はと仮定しています) everyヘッダーファイルには、#includeガードまたは#pragmaのような同等のものが1つあります。 message.hの作者が、リンクしたGotWをフォローして余分な#includeを削減することにした場合、知らないうちにoption.h/.cppを壊してしまうと、非常にイライラします。作業中に、いくつかのコードがGCCでコンパイルされるがClangではコンパイルされないことを発見しました。これは、いくつかの標準ライブラリ#includeが欠落しているため、特定のGCCヘッダーがお互いに#includeされているという事実に無意識のうちに依存していたためです。

したがって、元の質問への直接的な答えは次のとおりです。使用する予定のすべてのファイルにstring.hを直接含め、他のファイルは含めないでください。 option.h内でmemcpy()を使用していない場合(これはありそうにありません)は、#includeがoption.cppに属していることを意味します。

6
Ixrec