56

複数のソースファイルとヘッダーファイルにまたがる多数の相互依存クラスを処理する必要がある人々に提案するC++コーディングとファイル編成のガイドラインは何ですか?

私のプロジェクトではこのような状況にあり、いくつかのヘッダーファイルにまたがるクラス定義関連のエラーを解決することは非常に頭痛の種になっています。

4

6 に答える 6

78

いくつかの一般的なガイドライン:

  • インターフェイスを実装とペアリングします。がある場合はfoo.cxx、そこで定義されているすべてのものをで宣言することをお勧めしますfoo.h
  • すべてのヘッダーファイルに、独立したコンパイルに必要な他のすべてのヘッダーまたは前方宣言が含まれていることを確認してください。
  • 「すべて」のヘッダーを作成したいという誘惑に抵抗してください。彼らは常に将来的に問題を抱えています。
  • 関連する(および相互に依存する)機能のセットを1つのファイルに入れます。Javaおよびその他の環境では、ファイルごとに1つのクラスが推奨されます。C ++では、ファイルごとに1セットのクラスが必要になることがよくあります。コードの構造によって異なります。
  • #include可能な限り、sよりも前方宣言を優先します。これにより、循環ヘッダーの依存関係を解消できます。基本的に、個別のファイル間の循環依存関係の場合、次のようなファイル依存関係グラフが必要です。
    • A.cxx必要A.hB.h
    • B.cxx必要A.hB.h
    • A.h必要B.h
    • B.hは独立しています(およびで定義されたクラスを転送宣言しますA.h

コードが他の開発者によって使用されるライブラリであることが意図されている場合、実行することが重要ないくつかの追加の手順があります。

  • 必要に応じて、「プライベートヘッダー」の概念を使用してください。つまり、複数のソースファイルで必要とされるが、パブリックインターフェイスでは必要とされないヘッダーファイルです。これは、一般的なインライン関数、マクロ、または内部定数を含むファイルである可能性があります。
  • ファイルシステムレベルで、パブリックインターフェイスをプライベート実装から分離します。私はCまたはC++プロジェクトでサブディレクトリを使用する傾向があります。ここにinclude/は、すべてのパブリックヘッダーがあり、すべてのソースがあります。およびプライベートヘッダー。src/include/src/

JohnLakosの著書Large-ScaleC++SoftwareDesignのコピーを見つけることをお勧めします。かなり重い本ですが、物理的なアーキテクチャに関する彼の議論のいくつかをざっと見れば、多くのことを学ぶことができます。

于 2008-12-06T08:35:56.420 に答える
10

NASAゴダードスペースフライトセンターでCおよびC++コーディング標準を確認してください。私がC標準で特に注目し、自分のコードで採用した1つのルールは、ヘッダーファイルの「スタンドアロン」の性質を強制するルールです。ヘッダーxxx.hの実装ファイルxxx.cppで、xxx.hが最初に含まれるヘッダーであることを確認します。ヘッダーがいつでも自己完結型でない場合、コンパイルは失敗します。それは美しくシンプルで効果的なルールです。

失敗するのは、マシン間で移植する場合だけです。xxx.hヘッダーには、たとえば、が含まれますが、元のプラットフォームのヘッダーによってたまたま利用可能になる機能<pqr.h>が必要です(したがって、が含まれます)が、機能はそうではありません。他のプラットフォームで利用可能になりました(代わりに使用されますが、含まれていません)。これはルールの誤りではなく、ルールに従うと、問題の診断と修正がより簡単になります。<pqr.h><abc.h><pqr.h><abc.h><abc.h>def.h<pqr.h><def.h>

于 2008-12-06T11:11:25.403 に答える
6

Googleスタイルガイドのヘッダーファイルセクションを確認してください

于 2008-12-06T08:34:49.527 に答える
5

トムの答えは素晴らしいものです!

私が追加したい唯一のことは、ヘッダーファイルに「宣言を使用する」ことは決してないということです。それらは、実装ファイルでのみ許可する必要がありますfoo.cpp

このロジックは、優れた本「Accelerated C++」に詳しく説明されています ( Amazon リンク- スクリプト キディー リンク ナチスのためにサニタイズされています)。

于 2008-12-06T13:50:42.557 に答える
3

ここで他のものに加えてもう1つのポイント:

インクルードファイルにプライベート定義を含めないでください。たとえば、xxx.cppでのみ使用される定義は、xxx.hではなくxxx.cppに含める必要があります。

当たり前のようですが、よく見かけます。

于 2008-12-07T21:58:16.440 に答える
3

見捨てられがちな非常に優れたプラクティス (C と C++ の両方) を 1 つ追加したいと思います。

foo.c

#include "foo.h" // always the first directive

他の必要なヘッダーが続く必要があり、その後にコードを記述します。ポイントは、とにかくこのコンパイル単位のヘッダーがほとんど常に必要であり、それを最初のディレクティブとして含めることで、ヘッダーが自給自足のままであることを保証することです (そうでない場合、エラーが発生します)。これは特にパブリック ヘッダーに当てはまります。

任意の時点で、このヘッダー インクルードの前に何かを配置する必要がある場合 (もちろんコメントは除きます)、何か間違ったことをしている可能性があります。自分が何をしているのかを本当に理解していない限り...別のより重要なルールにつながります=>ハックにコメントしてください!

于 2013-06-30T07:04:52.260 に答える