2016-11-13 9 views
1

".h"ファイルにクラスを別に宣言し、 ".cpp"ファイルに 関数の実装を提供する必要があるのはいつですか?クラスを ".h"ファイルで個別に宣言し、関数の実装をC++の ".cpp"ファイルに提供する必要があるのはいつですか?

+1

プログラマーの時間がマシン時間よりも安かった歴史的な理由から、コンパイラに何を期待してそのチェックを行うのかを '.h'で伝えます。プログラミング時代との互換性のために、これは今日もなお使用されています。 – Robert

+2

@Robert "プログラミング時代との互換性"のためだけでなく、コンパイル時間を短縮するために広く使われています。編集時間は面倒かもしれません。 –

+0

@ Peregring-lkオブジェクトファイルを保持すると、コンパイル時間は短縮されます。コンパイラは '.h'の代わりに' .cpp'を見ることができます。そうすれば、プログラマは '.h'と' .cpp'ファイルの間ですべての情報を複製することを余儀なくされるでしょう。 – Robert

答えて

0

通常それは、クラス定義(.h)とクラスの実装(.cpp)の人々の間の良好な分離がちょうど実装の詳細を読んで悩まずにクラスを知って.hファイルを読み込み、使用ことができます。

しかし、必ず.h.cppを分けることは必須ではありません。クラス定義と実装を1つのファイル(たとえば、いくつかの単純なクラスやいくつかのクイックプロトタイプなど)にすることができます。

+0

ヘッダーファイルにすべてのプライベートクラスメンバーが表示されるため、ヘッダーファイルは実装の詳細を隠すのにはうってつけです。 – Robert

+0

@Robert実際、ヘッダーファイルを見ると、実装について知っておく必要がある以上のことが分かっています(つまり、プライベートメンバー)。私は情報が隠れていることは言及しなかった。私はクラスヘッダーを見て** **それを使う方が便利だと言いました。 – artm

1

このようにして、クラスのコードを1回だけ作成します。 クラスのコードを.hファイルに入れると、(クラスのパブリック関数にアクセスするために).hを受け取るすべてのファイルもクラスのコードを複製します。 コンパイラはこれをうれしく行います。 しかし、リンカは名前空間の重複した左辺値について強く訴えるでしょう。同じ線に沿って

、まだ逆:そのコードが正確にインライン関数の意図である、他のコードファイルにを拾ってしまいますようにインライン関数.hにする必要があります。

1

C++言語に関する限り、厳密には必要ではありません。すべてのクラスメソッドを.hファイルにインラインで入れることができます。

しかし、別々の.cppへの実装を置くことなど、多くのメリット、提供しています:

  1. C++は非常に複雑です。コードが大きくなるにつれて、コンパイルに時間がかかります。同じヘッダファイルを含むすべての.cppファイルは、同じコードを何度も繰り返しコンパイルされます。最初のポイントに関連する

  2. :任意の変更は、クラスのメソッドに行われた場合、すべてのクラスメソッドは、別の.cppファイル内にある場合は、それだけで.cppニーズの再コンパイル。すべてのクラスメソッドが.hファイルにインラインで配置されている場合は、含まれる.cppのすべてを再コンパイルする必要があります。

  3. 非常に多くの場合、クラスのメソッドは、必要な処理を行うために、他のクラスも使用します。したがって、すべてが.hファイルのインラインに配置されている場合は、他のクラスを定義する.hファイルも含めて、ヘッダファイルを含むファイル.cppのコンパイルを遅くする必要があります。クラスメソッドが別のファイル.cppにある場合、.cppファイルにのみ他のヘッダーを含める必要があります。ほとんどの場合、前方宣言を.hに追加するだけです。

+0

なぜ時間差が大きいのかを具体的に説明すると、関数宣言はマシンコードを生成せず、呼び出すときにタイプするだけです。クラスはもう少し複雑ですが、メンバ関数の場合は同じロジックが適用されます。また、関数定義をコンパイラーに提供しないで、コンパイラーが(呼び出し元から)最適化を検索してしまうのを避けます。 –

1

あなたが* .hファイルで表示されるようにしたくない宣言、/実装する関数を定義するための宣言を使用する場合は、関数の定義を移動する必要があります別のファイル。

0

技術的な観点から(コンパイラが必要とする、または受け入れるという点で)ほとんど必要ありません。すべての(標準ではない)ヘッダーファイルの内容をコピーして、それらをコンパイルしてください。結局のところ、それは効果的にプリプロセッサが#includeディレクティブで行うことです - インクルードされたファイルを所定の場所にコピーし、その後コンパイラの後の段階に結果のソースを送ります。

ソースをコンパイルするときにコンパイラがメモリ不足になる可能性があります。この場合、プログラムをヘッダーファイルなどの小さな部分に分割すると役立ちますが、このような状況(ハードウェアリソースが非常に限られているマシンメモリ)は、現代開発においては非常にまれです。

しかし、人間は、ソースファイルを扱うときにコンパイラよりも一貫性が低く、エラーが発生しやすいので、人間はヘッダファイルを使用することで利益を得ます。たとえば、必要な宣言を必要とするすべてのソースファイル(人が退屈で、間違いを犯す傾向があるアクティビティ)に必要な宣言を入力(またはコピー)するのではなく、宣言をヘッダファイルに入れ、必要な場合にはそれを#includeに置きます。

それで、ヘッダーファイルに宣言を置くことで、人間の生活が楽になり、エラーを避けることができ、ソフトウェア開発の創造的な部分(新しいものを実装する)に集中することができます。機械的(それらを必要とするソースファイルへの関数宣言のコピー)。

実際には、複数のコンパイル単位(別名ソースファイル)内で使用されるクラスは、ヘッダーファイルで定義する方がよいということが実際にはあります。単一のコンパイル単位に対してローカルなクラス(例えば、他の人が直接アクセスする必要のないコンパイル単位の実装の詳細を含む)は、ヘッダファイル内にある必要はありません。ヘッダー。このような「ローカル」クラスが後で他のコンパイル単位で使用される必要がある場合、問題が発生します。この場合、必要な宣言をヘッダーファイルに移行して再利用することをお勧めします。

ヘッダーファイルは、他のプログラマーが使用するために一連の関数を書きますが、ソースを出荷したくないライブラリ作成者には必要になりがちです。これは技術的制約ではなく、技術的ではない制約(つまりポリシーベース)です。その場合、ヘッダファイルとコンパイルされたオブジェクト(またはライブラリ)ファイルを配布し、ソースコードを非公開にすることができます。もちろん、技術的には、ヘッダーファイルの代わりに "これらの宣言をあなたのプログラムにコピーする"という形式のテキストファイルセットを提供することもできますが、それは開発者にとって不評のライブラリになりますそれは、それらが、有用な開発を行うのではなく、テキストをコピーするという、平凡で誤りがちな活動に戻さなければならないからです。

コンパイル時間を短縮するような考慮事項は技術的な理由もありません(コンパイラーはプログラムの作成にどれくらい時間がかかりますが、人はそうです)。クラス定義をヘッダー(クラス定義、インライン関数)と別のソース(非インラインメンバー関数の定義)に分けることは、ビルド時間を短縮し、インクリメンタルビルドを支援する傾向があります。

関連する問題