ヘッダーを持つ意味がよくわかりません。DRYの原則に違反しているようです!ヘッダー内のすべての情報は、実装に含まれています (含めることができます)。
9 に答える
これにより、コンパイル プロセスが簡素化されます。ユニットを個別にコンパイルしたい場合、他のすべてのファイル全体をインポートすることなく、リンクされる部分を記述する何かが必要です。
また、コードを隠すこともできます。ヘッダーを配布して、実装を配布しなくても他のユーザーが機能を使用できるようにすることができます。
最後に、実装からのインターフェースの分離を促進できます。
これらの問題を解決する唯一の方法ではありませんが、30 年前には優れた方法でした。今日の言語ではおそらくヘッダー ファイルを使用しないでしょうが、ヘッダー ファイルは 2009 年に発明されたものではありません。
Java、Eiffel、C# などの多くの最新言語のアーキテクトは、明らかにあなたに同意します。これらの言語は、実装からモジュールに関するメタデータを抽出します。ただし、それ自体、ヘッダーの概念はそれを排除するものではありません。たとえば、他の言語のコンパイラが暗黙的に行うのと同じように、コンパイラが.h
をコンパイルしている間にファイルを抽出するのは明らかに単純な作業です。.c
典型的な現在の C コンパイラがそれを行わないという事実は、言語設計の問題ではなく、実装の問題です。どうやらそのような機能に対するユーザーの要求はないようです。そのため、わざわざ実装するコンパイラ ベンダーはありません。
言語設計の選択肢として、別々の.h
ファイル (人間が読める編集可能なテキスト形式) を持つことで、両方の利点を得ることができます: 必要に応じて、まだ存在しないモジュール実装に基づいてクライアント コードを個別にコンパイルし始めることができます。 、.h
手でファイルを書くことによって; または、(それを提供するコンパイラの実装がばかげていると仮定して;-).h
コンパイルの副作用として、実装からファイルを自動的に取得できます。
C、C++、&c が繁栄し続け (どうやらそれらは今日もうまくいっているようです;-)、ヘッダーを手動で書かないことに対するあなたのような需要が高まると、最終的にコンパイラの作成者は「ヘッダー生成」オプションを提供する必要があり、「両方の世界のベスト" 理論にとどまることはありません!-)
たとえば、c が作成されたときに使用可能だったコンピューターの機能について少し考えてみると役に立ちます。メインメモリはキロワード単位で測定され、必ずしも非常に多くはありませんでした. ディスクは大きくなりましたが、それほど大きくはありませんでした。深刻なストレージとはオープン リール テープを意味し、不機嫌そうなオペレーターが手でマウントしたものでした。1 MIPS のマシンが高速で叫んでいました。そして、これらすべての制限により、あなたはそれを共有しなければなりませんでした. おそらく他のユーザーのスコアで。
コンパイルのスペースや時間の複雑さを軽減したことは、大きな成果でした。そしてヘッダーは両方を行います。
ヘッダーが提供するドキュメントを忘れないでください。通常、モジュールを使用するために知っておく必要のあることがあります。私は、使用する必要のあるものとその呼び出し方法を知るために、非常に長いソースコードをスキャンしたくありません...とにかくこの情報を抽出すると、事実上、ヘッダーファイルになります。もちろん、最近のIDEの問題ではなくなりましたが、古いCコードを使用して作業する場合は、使用法や事前条件と事後条件に関するコメントを含む手作りのヘッダーファイルが大好きです。
ソース、ヘッダー、および追加のドキュメントの同期を維持することは、ワームのもう1つの可能性です...
C がファイルを発明したときには、言語プロセッサのバイナリ出力ファイルを検査するという全体的なアイデアを理解するのは困難でした.h
。似たようなことをするJOVIALというシステムがありましたが、それは風変わりで、多かれ少なかれ軍事プロジェクトに限定されていました。(私は JOVIAL プログラムを見たことがなく、聞いただけです。)
したがって、C が登場したとき、モジュール性のための通常の設計パターンは「まったくチェックなし」でした。.text シンボルは .text に、.data は .data にしかリンクできないという制限があるかもしれませんが、それだけです。つまり、当時のコンパイラは通常、一度に 1 つのソース ファイルを処理し、リンカは、運が良ければ「関数シンボルです」と「私はデータシンボル」。
したがって、呼び出しているものを実際にコンパイラーに理解させるという考えは、やや新しいものでした。
今日でも、完全に偽のヘッダーを作成しても、ほとんどのAOT コンパイラでは誰もあなたを捕まえません。CLR 言語や Java などの巧妙なものは、実際にクラス ファイル内でエンコードを行います。
そうです、長期的には、おそらくヘッダー ファイルはありません。
いいえ、Javaにはヘッダーがありませんが、インターフェイスはあります。Javaの第一人者なら誰でも、他のプロジェクトやシステムで使用されるものをインターフェイスと実装として定義することをお勧めします。
Javaインターフェース定義に、呼び出しシグネチャ、型定義、および定数が含まれていることを確認してください。
MOST Cヘッダーファイルには、呼び出しシグネチャ、型定義、および定数が含まれています。
したがって、すべての実用的な目的で、C / C ++ヘッダーファイルは単なるインターフェイス定義であり、したがって、良いことと見なす必要があります。これで、ヘッダーファイルでも無数の他のもの(MARCRO、定数など)を定義できることがわかりましたが、それはCのすばらしい世界全体のほんの一部です:-
int function target () {
// Default for shoot
return FOOT;
}
コードをヘッダーファイルとソースファイルに分割するときは、宣言と定義を分割します。ヘッダーファイルを見ると、自分が持っているものを確認できます。実装の詳細を確認したい場合は、ソースファイルに移動します。
また、実装を提供せずに、ライブラリを使用する宣言を他の誰かに提供したい場合はどうすればよいでしょうか?
別の回答が指摘しているように、ヘッダーの本来の理由は、非常に単純で限られたツールを使用して、プラットフォームでの解析/コンパイルを容易にすることでした。2 つのフロッピーを備えたマシンを用意したことは大きな前進であり、一方にコンパイラーを、もう一方にコードを入れることができ、作業がずっと簡単になりました。