複数のソースファイルとヘッダーファイルにまたがる多数の相互依存クラスを処理する必要がある人に提案する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/
にはすべてのソースがあります。プライベートヘッダー。John Lakosの本Large-Scale C++ Software Designのコピーを見つけることをお勧めします。かなり高額な本ですが、物理アーキテクチャに関する彼の議論のいくつかをざっと見れば、たくさん学ぶことができます。
NASA Goddard Space Flight Center で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>
が含まれていません)。これはルールの誤りではなく、ルールに従うと問題の診断と修正がより簡単になります。
私はしばしば見捨てられている非常に良い習慣を1つ追加したいと思います(CとC++の両方で):
#include "foo.h" // always the first directive
他の必要なヘッダーが続き、コードを記述します。重要なのは、とにかくこのコンパイルユニットのヘッダーがほとんど常に必要であり、最初のディレクティブとしてヘッダーを含めるとヘッダーが十分であることを保証することです(そうでない場合、エラーが発生します)。これは特にパブリックヘッダーに当てはまります。
このヘッダーインクルードの前に何かを置く必要がある場合(もちろん、コメントを除く)、何か間違っている可能性があります。あなたが本当にあなたが何をしているのかを知らない限り...それは別のより重要なルールにつながります=>あなたのハックをコメントしてください!
ここで他のポイントに加えてもう1つポイント:
インクルードファイルにプライベート定義を含めないでください。例えば。 xxx.cppでのみ使用される定義は、xxx.hではなくxxx.cppである必要があります。
当たり前のようですが、よく目にします。