web-dev-qa-db-ja.com

ヘッダーを別のディレクトリに配置するのはなぜですか?

C/C++プロジェクトでは、ヘッダーファイルをincludeなどのディレクトリに配置し、実装をsrcなどの別のディレクトリに配置するのが一般的であることを知っています。私はさまざまなプロジェクト構造をいじっていて、これには客観的な理由があるのか​​、それとも単なる慣習なのか疑問に思っています。

23
Doug Moore

慣習が理由の1つです。ほとんどの場合、効果的な抽象化により、インターフェースのみに関心があり、ヘッダーを見るだけで簡単にしたい場合があります。

理由はそれだけではありません。プロジェクトがモジュールで構成されている場合、おそらくいくつかのヘッダーを別のモジュールに含める必要があり、インクルードディレクトリから他の「ノイズ」ファイルを削除する必要があります。

また、モジュールの再配布を計画している場合は、実装の詳細を非表示にする必要があります。そのため、ヘッダーとバイナリのみを提供します-そして、他に何もない単一のフォルダーからヘッダーを配布する方が簡単です。

私が実際に好む代替もあります-パブリックヘッダーは別のフォルダーに格納され(これらには最小限のインターフェイスが含まれます-実装の詳細はまったく表示されません)、プライベートヘッダーと実装ファイルは別です(おそらく、必ずしもそうとは限りません)。

32
Luchian Grigore

私はそれらをsameディレクトリに置くことを好みます。理由:

インターフェイス仕様ファイル、およびそのインターフェイスを実装するソースファイルは、プロジェクトの同じ部分に属しています。あなたがsubsystemxを持っているとしましょう。次に、subsystemxファイルをsubsystemxディレクトリに配置すると、subsustemxは自己完結型になります。

多くのインクルードファイルがある場合は、subsystemx/includesubsystemx/sourceを実行できますが、class Fooの定義をfoo.hppに入れて、foo.cppあなたは確かにディレクトリリストでそれらの両方を一緒に見たいと思っています(または少なくとも簡単にそうする可能性があります)。 fooに関連するすべてのファイルを検索しています

ls foo*

すべての実装ファイルを見つける:

ls *.cpp

すべての宣言ファイルを見つける:

ls *.hpp

シンプルでクリーン。

7
user877329

それはあなたのフォルダー構造をよりきれいに保ちます。ヘッダーとソースファイルは明らかに異なり、さまざまな目的で使用されるため、それらを分離することは理にかなっています。この観点からの質問は、基本的には「ソースファイルとドキュメントが異なるフォルダーに移動する理由」と同じですか?コンピューターは、フォルダーに何を入れ、何を入れないかについて非常に無知です。フォルダーは、ほとんどの場合、人間が情報を解析、保存、および呼び出す方法があるため、便利な抽象概念です。

ヘッダーファイルが有用なままであるという事実もありますビルドした後でも、つまり、ライブラリをビルドしていて、誰かがそのライブラリを使用したい場合、ヘッダーファイルは必要ですが、ソースファイル-ヘッダーファイルをまとめる-binの内容とincludeの内容を取得し、srcをふるいにかける必要がない-はるかに簡単。

物事を秩序正しく維持するための(議論の余地がある?)有用性、他のプロジェクトなどでの有用性に加えて、非常に中立的で客観的な利点が1つあります。それはコンパイル時間です。

特に、ヘッダーの検索パス(#include "headername.h"ではなく#include "../../gfx/misc/something/headername.h"を使用した.c/.cppファイル)に応じて、ファイル全体が含まれる大きなプロジェクトでは、コンパイラーは正しいパラメーターをそれを飲み込むことができます)正しいヘッダーを探すためにコンパイラーがスキャンする必要のあるエントリーの数を大幅に減らします。ほとんどのコンパイラは、コンパイルされたファイルごとに個別に起動するため、インクルードパス上のファイルのリストを読み取り、コンパイルされた各ファイルの適切なヘッダーを探す必要があります。インクルードパスに一連の.c、.o、およびその他の無関係なファイルがある場合、それらの間でインクルードを見つけるのに比例して時間がかかります。

3
SF.

要するに、いくつかの理由:

  • 保守可能なコード。
  • コードは適切に設計されており、きちんとしています。
  • コンパイル時間が短縮されます(マイナーな変更が行われた場合).
  • 文書化などのためのインターフェースの分離の容易化.
  • コンパイル時の循環依存を回避できます。
  • 簡単に確認できます。

記事 CおよびC++でのコードファイルの整理 をご覧ください。

0
parasrish