2010-12-25 5 views
6

私のC++コードをすべて.hファイルに入れることができるのであれば、.cppファイルを使用するのはなぜですか?私は、.cppファイルは、すべてのコードが.hファイルに書き込めるのであれば、かなり奇妙なことを意味していますか?どの人もはっきりしていますか?私のC++コードをすべて.hファイルに入れることができるのであれば、.cppファイルを使用するのはなぜですか?

答えて

7

いくつかの理由:

(1)インクリメンタルプロジェクトが大きく成長すると、ビルド時間を管理することはC++プロジェクトのために特に問題となるタイムズ

を構築します。マイナーチェンジの1〜5分後にビルドすると大きな違いがあります。これは、大きなプロジェクトのほとんどが小さなに変更されていることが多くのテストを必要とすることが強調されています。それにTDDとリファクタリングの試みを加え、あなたはシチリアの靴で死んだスラッグです。

ヘッダーとボディに分割してlibsに移動すると、増分ビルド時間が大幅に短縮されます。あなたがタイプの単一のインスタンスを必要とする多くのものについては

(2)静
、すなわち

// .cpp 
static Foo foo; 

ない方法(私の知ること)header-でこれを許可するがありませんプロジェクトのみ。コンパイラ固有のソリューションは限られています。 MSVCの__declspec(selectany)はPODタイプに限定されています。

(3)実施隠蔽
の.cpp/.hの分離が明確実装の詳細からパブリックインターフェースを分離する唯一の方法です。クラスメンバーをprivateセクションにスローすることはできますが、それは他のエンティティでは機能しません。 (たとえPIMPLのような追加のテクニックを追加しなければ、ヘッダー/ボディの分離さえも漏れているので、この引数は少し弱いIMOですが、大規模なプロジェクトでは、不完全な場合にはこの効率的な方法が間違っています)。


とにかくグレート質問、 - あなたは何かが、私は恐ろしい意味合いの古代の遺物を検討C/C++ビルドモデルとの抵触があることを認識しました。

"ヘッダーのみ"モデル(または、ほとんどの場合、 "ほとんどのヘッダー")を押すことで、静的な状態を可能にすることができます。あなたはかなり遠くにいるかもしれません - 試した人から聞くのも面白いでしょう。

実装を分離してカプセル化するために静的ライブラリを使用し、ヘッダ内にすべてのコードを保持することをお勧めします。私はそれにいくつかの問題を見ることができますが、それは私たちの現在のmodus operandiは問題がないことです。

+4

+1を呼び出すC/C++ビルド/リンクモデルは本当に悲惨です –

2

ヘッダーファイル(.h)は、クラスとコードを他の翻訳単位で使用できるようにインターフェイスを定義するためのものです。 .hファイルにインプリメンテーションを配置すると、同じコードの複数のコピーが作成され、.hファイルを含む各翻訳単位にコンパイルされます。これは、あなたのコードを小さな断片に分割することを打ち消し、孤立して研究開発することができます。

+0

私はこれを行うことができると思います。あなたが 'details \'サブフォルダを使っているのと同じように、 "実装ヘッダー"を含むヘッダーにパブリックインターフェイスを置くことができます。インターフェイスを多用することなく、.h/.cppの分離は、インターフェイスと実装の分離に非常によく一致しません。 – peterchen

3

すべてのコードを.hファイルに入れることができます。普遍的な信念に反して、これはあなたの.objファイルにコードを複製しません。現代のコンパイラはそれよりずっとスマートです。

コンパイルには多少の問題があります。 20個の.hファイルがすべてmain.cppに含まれていれば、main.cppをコンパイルするのにしばらく時間がかかります。また、インクルードファイルの1つが変更されるたびに、20個のインプリメンテーション.hファイルをすべて再コンパイルします。

スタイルがあります。それはちょうど私に間違って見えます。しかしこれは好みの問題です。

次に参照があります。 ClassAがClassBを使用していて、ClassBがClassAを使用している場合、どちらを先に含めますか?

+0

現代のコンパイラがどこに入ってくるのかわかりません。実装でヘッダーファイルを含む複数の翻訳単位を取得したら、オブジェクトファイルにコードを複製します。はい、理論的には、この複製は削除することができますが、それはコンパイラではなくリンカによって行わなければなりません。 –

+0

リンカとコンパイラの役割についてのあなたの前提はかなり古くなっています。リンク時コードの生成は、現在10年にわたって広く使用されています。 LTCGでは、コンパイラはちょっとしたプリプロセッサに過ぎません。.objファイルには実際にはマシンコードは含まれていません。そして、重複した(そして不要な、等々の)コードを削除することができます。 – martona

+0

すべてが非常に巧妙に聞こえる - ちょうどそれはC/C++の時代遅れのビルドモデルに対処するために必要です! –