複数のソースファイルとヘッダーファイルにまたがる多数の相互依存クラスを処理する必要がある人々に提案するC++コーディングとファイル編成のガイドラインは何ですか?
私のプロジェクトではこのような状況にあり、いくつかのヘッダーファイルにまたがるクラス定義関連のエラーを解決することは非常に頭痛の種になっています。
複数のソースファイルとヘッダーファイルにまたがる多数の相互依存クラスを処理する必要がある人々に提案するC++コーディングとファイル編成のガイドラインは何ですか?
私のプロジェクトではこのような状況にあり、いくつかのヘッダーファイルにまたがるクラス定義関連のエラーを解決することは非常に頭痛の種になっています。
いくつかの一般的なガイドライン:
foo.cxx
、そこで定義されているすべてのものをで宣言することをお勧めしますfoo.h
。#include
可能な限り、sよりも前方宣言を優先します。これにより、循環ヘッダーの依存関係を解消できます。基本的に、個別のファイル間の循環依存関係の場合、次のようなファイル依存関係グラフが必要です。
A.cxx
必要A.h
とB.h
B.cxx
必要A.h
とB.h
A.h
必要B.h
B.h
は独立しています(およびで定義されたクラスを転送宣言しますA.h
)コードが他の開発者によって使用されるライブラリであることが意図されている場合、実行することが重要ないくつかの追加の手順があります。
include/
は、すべてのパブリックヘッダーがあり、すべてのソースがあります。およびプライベートヘッダー。src/
include/
src/
JohnLakosの著書Large-ScaleC++SoftwareDesignのコピーを見つけることをお勧めします。かなり重い本ですが、物理的なアーキテクチャに関する彼の議論のいくつかをざっと見れば、多くのことを学ぶことができます。
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>
Googleスタイルガイドのヘッダーファイルセクションを確認してください
トムの答えは素晴らしいものです!
私が追加したい唯一のことは、ヘッダーファイルに「宣言を使用する」ことは決してないということです。それらは、実装ファイルでのみ許可する必要がありますfoo.cpp
。
このロジックは、優れた本「Accelerated C++」に詳しく説明されています ( Amazon リンク- スクリプト キディー リンク ナチスのためにサニタイズされています)。
ここで他のものに加えてもう1つのポイント:
インクルードファイルにプライベート定義を含めないでください。たとえば、xxx.cppでのみ使用される定義は、xxx.hではなくxxx.cppに含める必要があります。
当たり前のようですが、よく見かけます。
見捨てられがちな非常に優れたプラクティス (C と C++ の両方) を 1 つ追加したいと思います。
#include "foo.h" // always the first directive
他の必要なヘッダーが続く必要があり、その後にコードを記述します。ポイントは、とにかくこのコンパイル単位のヘッダーがほとんど常に必要であり、それを最初のディレクティブとして含めることで、ヘッダーが自給自足のままであることを保証することです (そうでない場合、エラーが発生します)。これは特にパブリック ヘッダーに当てはまります。
任意の時点で、このヘッダー インクルードの前に何かを配置する必要がある場合 (もちろんコメントは除きます)、何か間違ったことをしている可能性があります。自分が何をしているのかを本当に理解していない限り...別のより重要なルールにつながります=>ハックにコメントしてください!