".h"ファイルにクラスを別に宣言し、 ".cpp"ファイルに 関数の実装を提供する必要があるのはいつですか?クラスを ".h"ファイルで個別に宣言し、関数の実装をC++の ".cpp"ファイルに提供する必要があるのはいつですか?
答えて
通常それは、クラス定義(.h
)とクラスの実装(.cpp
)の人々の間の良好な分離がちょうど実装の詳細を読んで悩まずにクラスを知って.h
ファイルを読み込み、使用ことができます。
しかし、必ず.h
と.cpp
を分けることは必須ではありません。クラス定義と実装を1つのファイル(たとえば、いくつかの単純なクラスやいくつかのクイックプロトタイプなど)にすることができます。
このようにして、クラスのコードを1回だけ作成します。 クラスのコードを.h
ファイルに入れると、(クラスのパブリック関数にアクセスするために).h
を受け取るすべてのファイルもクラスのコードを複製します。 コンパイラはこれをうれしく行います。 しかし、リンカは名前空間の重複した左辺値について強く訴えるでしょう。同じ線に沿って
、まだ逆:そのコードがが正確にインライン関数の意図である、他のコードファイルにを拾ってしまいますようにインライン関数は.h
にする必要があります。
C++言語に関する限り、厳密には必要ではありません。すべてのクラスメソッドを.h
ファイルにインラインで入れることができます。
しかし、別々の.cpp
への実装を置くことなど、多くのメリット、提供しています:
C++は非常に複雑です。コードが大きくなるにつれて、コンパイルに時間がかかります。同じヘッダファイルを含むすべての
.cpp
ファイルは、同じコードを何度も繰り返しコンパイルされます。最初のポイントに関連する:任意の変更は、クラスのメソッドに行われた場合、すべてのクラスメソッドは、別の
.cpp
ファイル内にある場合は、それだけで.cpp
ニーズの再コンパイル。すべてのクラスメソッドが.h
ファイルにインラインで配置されている場合は、含まれる.cpp
のすべてを再コンパイルする必要があります。非常に多くの場合、クラスのメソッドは、必要な処理を行うために、他のクラスも使用します。したがって、すべてが
.h
ファイルのインラインに配置されている場合は、他のクラスを定義する.h
ファイルも含めて、ヘッダファイルを含むファイル.cpp
のコンパイルを遅くする必要があります。クラスメソッドが別のファイル.cpp
にある場合、.cpp
ファイルにのみ他のヘッダーを含める必要があります。ほとんどの場合、前方宣言を.h
に追加するだけです。
なぜ時間差が大きいのかを具体的に説明すると、関数宣言はマシンコードを生成せず、呼び出すときにタイプするだけです。クラスはもう少し複雑ですが、メンバ関数の場合は同じロジックが適用されます。また、関数定義をコンパイラーに提供しないで、コンパイラーが(呼び出し元から)最適化を検索してしまうのを避けます。 –
あなたが* .hファイルで表示されるようにしたくない宣言、/実装する関数を定義するための宣言を使用する場合は、関数の定義を移動する必要があります別のファイル。
技術的な観点から(コンパイラが必要とする、または受け入れるという点で)ほとんど必要ありません。すべての(標準ではない)ヘッダーファイルの内容をコピーして、それらをコンパイルしてください。結局のところ、それは効果的にプリプロセッサが#include
ディレクティブで行うことです - インクルードされたファイルを所定の場所にコピーし、その後コンパイラの後の段階に結果のソースを送ります。
ソースをコンパイルするときにコンパイラがメモリ不足になる可能性があります。この場合、プログラムをヘッダーファイルなどの小さな部分に分割すると役立ちますが、このような状況(ハードウェアリソースが非常に限られているマシンメモリ)は、現代開発においては非常にまれです。
しかし、人間は、ソースファイルを扱うときにコンパイラよりも一貫性が低く、エラーが発生しやすいので、人間はヘッダファイルを使用することで利益を得ます。たとえば、必要な宣言を必要とするすべてのソースファイル(人が退屈で、間違いを犯す傾向があるアクティビティ)に必要な宣言を入力(またはコピー)するのではなく、宣言をヘッダファイルに入れ、必要な場合にはそれを#include
に置きます。
それで、ヘッダーファイルに宣言を置くことで、人間の生活が楽になり、エラーを避けることができ、ソフトウェア開発の創造的な部分(新しいものを実装する)に集中することができます。機械的(それらを必要とするソースファイルへの関数宣言のコピー)。
実際には、複数のコンパイル単位(別名ソースファイル)内で使用されるクラスは、ヘッダーファイルで定義する方がよいということが実際にはあります。単一のコンパイル単位に対してローカルなクラス(例えば、他の人が直接アクセスする必要のないコンパイル単位の実装の詳細を含む)は、ヘッダファイル内にある必要はありません。ヘッダー。このような「ローカル」クラスが後で他のコンパイル単位で使用される必要がある場合、問題が発生します。この場合、必要な宣言をヘッダーファイルに移行して再利用することをお勧めします。
ヘッダーファイルは、他のプログラマーが使用するために一連の関数を書きますが、ソースを出荷したくないライブラリ作成者には必要になりがちです。これは技術的制約ではなく、技術的ではない制約(つまりポリシーベース)です。その場合、ヘッダファイルとコンパイルされたオブジェクト(またはライブラリ)ファイルを配布し、ソースコードを非公開にすることができます。もちろん、技術的には、ヘッダーファイルの代わりに "これらの宣言をあなたのプログラムにコピーする"という形式のテキストファイルセットを提供することもできますが、それは開発者にとって不評のライブラリになりますそれは、それらが、有用な開発を行うのではなく、テキストをコピーするという、平凡で誤りがちな活動に戻さなければならないからです。
コンパイル時間を短縮するような考慮事項は技術的な理由もありません(コンパイラーはプログラムの作成にどれくらい時間がかかりますが、人はそうです)。クラス定義をヘッダー(クラス定義、インライン関数)と別のソース(非インラインメンバー関数の定義)に分けることは、ビルド時間を短縮し、インクリメンタルビルドを支援する傾向があります。
- 1. hとcppファイルのC++の競合するポインタ宣言
- 2. C++ - .cppファイルの.hファイルからクラス変数を取得する
- 3. .hファイル内または.cppファイル内でのクラスの実装の違い
- 4. C++関数プロトタイプが.hファイルのクラス定義で宣言されていますが、.cppで定義されていない関数
- 5. 演算子*はHで宣言さオペレータとCPPファイル
- 6. .cppファイルに実装されたC++/CX WinRTプロパティを宣言する構文は何ですか?
- 7. C++(クラス)では、常にヘッダファイルに関数を宣言する必要がありますか?
- 8. 宣言が必要CPP
- 9. 各.hファイルには、他の.hファイルに定義されている構造体が必要ですか? (C)
- 10. Obj-C関数宣言にセミコロンが必要ですか?
- 11. ヘッダーファイルで宣言された変数の型をC++ファイルに記述する必要はありますか?
- 12. POD構造体を.hファイルまたは.cppファイルに配置する必要がありますか?
- 13. インターフェイスをC#で.hファイルに実装できますか?
- 14. Cで関数を宣言する必要はありますか?
- 15. C++でヘッダ宣言のクラス宣言が必要
- 16. 別のドッカーコンテナにnginxがある静的ファイルを提供する
- 17. Objective C:実装ファイルで宣言されたIVarsを持つARC
- 18. JAX-RS実装用にインタフェースを宣言する必要があるのはなぜですか?
- 19. C++の継承 - "::" s、.hファイル、.cppファイルの使用を含む関数のオーバーライド
- 20. Typescript:実装しないで関数を宣言する
- 21. ヘッダとcファイルに関数ポインタを宣言するには?
- 22. クラス宣言とその実装を2つのファイルに分けて、IDEなしでコンパイルする方法は?
- 23. なぜC++テンプレートパラメータをクラス型として宣言する必要がありますか?関数テンプレートの
- 24. GroceryItemクラスで関数を実装するのに手助けが必要です
- 25. .hファイルが.cppファイルに含まれているのはなぜですか?その逆はありません。
- 26. 関数の宣言と実装の両方に初期化リストを書く必要がありますか?
- 27. .cppファイルと.hファイルの違いは何ですか?
- 28. 複数のクラスが1つの.cppファイルにあります
- 29. フォワード宣言を使用してクラスをファイルの末尾に移動する必要がありますか?
- 30. エラー:クラスを抽象宣言するか、残りのメソッドを実装する必要があります
プログラマーの時間がマシン時間よりも安かった歴史的な理由から、コンパイラに何を期待してそのチェックを行うのかを '.h'で伝えます。プログラミング時代との互換性のために、これは今日もなお使用されています。 – Robert
@Robert "プログラミング時代との互換性"のためだけでなく、コンパイル時間を短縮するために広く使われています。編集時間は面倒かもしれません。 –
@ Peregring-lkオブジェクトファイルを保持すると、コンパイル時間は短縮されます。コンパイラは '.h'の代わりに' .cpp'を見ることができます。そうすれば、プログラマは '.h'と' .cpp'ファイルの間ですべての情報を複製することを余儀なくされるでしょう。 – Robert