.h ファイルのセットが古典的な「ゴルディアン ノット」状況の犠牲になった場合、どうしますか? 予防が最善の薬であることは明らかですが、ベンダー (!) がライブラリを出荷する前にこれが起こった場合はどうしますか?
これが質問の拡張です。これはおそらくより適切な質問です-そもそも依存関係を解きほぐそうとする必要がありますか?;
.h ファイルのセットが古典的な「ゴルディアン ノット」状況の犠牲になった場合、どうしますか? 予防が最善の薬であることは明らかですが、ベンダー (!) がライブラリを出荷する前にこれが起こった場合はどうしますか?
これが質問の拡張です。これはおそらくより適切な質問です-そもそも依存関係を解きほぐそうとする必要がありますか?;
私はこれを、すでに多くのライブラリに分割されているC ++コードベースで実行しました(これは良いスタートでした)。
どのライブラリが最も依存しているか、コードベースの他の何にも依存していないかを調べなければなりませんでした。次に、各ライブラリを順番に処理しました。
各モジュール(* .cppファイル)を順番に調べて、独自のヘッダーが最初に#includeされ、残りがコメントアウトされていることを確認してから、そのヘッダーファイル内のすべての#includesをコメントアウトして、そのモジュールだけを再コンパイルしました。コンパイラに何が必要かを教えてもらいます。必要と思われる最初のヘッダーのコメントを外し、必要に応じて繰り返し、そのヘッダーを確認しました。必要のないヘッダーがいくつあるかを見るのは興味深いことでした。
名前だけが必要な場合(ポインタまたは参照があるため)、class name;
またはstruct name;
を使用します。これは前方宣言と呼ばれ、ヘッダーファイルを含めないようにします。
コンパイラは、#includesをコメントアウトするときに依存関係が何であるかを通知するのに非常に役立ちます(移植性を維持するために必要なすべてのコンパイラで再コンパイルする必要があります)。
ライブラリのペアやグループが相互に依存しないように、ライブラリ間でモジュールを移動しなければならない場合がありました。
機会があれば、コードをリファクタリングして、大きすぎるインクルードを減らす必要がありますが、これは、ある種のパッケージのまとまりを実現できることを前提としています。コードのすべてのユーザーがとにかくすべての要素を含める必要があることを発見するためだけに物事を解きほぐすと、最終結果は同じになります。
もう1つのオプションは、#definesを使用してセクションのオンとオフを構成することです。とにかく、既存のコードベースの場合、解決策はパッケージのまとまりに移行することです。
読む: http: //ivanov.files.wordpress.com/2007/02/sedpackages.pdfおよびパッケージの凝集に関連する調査の問題。
私はその結び目を数回解きました、そしてそれは一般的にシステムを維持するときに.h依存関係を可能な限り減らすのに大いに役立ちます。依存関係ツリーを生成するための適切なツールがあります(私は当時Klocworkを使用していました)。
私が見つけた欠点は、条件付きコンパイルにありました。誰かがヘッダーファイルを必要ないと思って削除するかもしれませんが、VxWorksにはいくつかのめちゃくちゃなヘッダーがあるので必要ないことがわかりました... Solaris(または任意の合理的なPosixシステム)では必要ですそれ。
細かく整理された膨大な数のヘッダーと、すべてを含む 1 つのヘッダーとの間でバランスを取る必要があります。標準 C ライブラリを考えてみましょう。多くの関数を宣言する のような大きなヘッダーがいくつかあります<stdio.h>
が、それらはすべて I/O に関連しています。雑多なヘッダーが他にもあります - 特に<stdlib.h>
.
C のゴダード宇宙飛行センターのガイドラインは、探し出す価値があります。
基本的なルールは、適切な (通常は小さい) ソース ファイルのセットによって提供される機能を各ヘッダーで宣言する必要があるということです。ファシリティとヘッダーは自己完結型である必要があります。つまり、誰かが header のコードを必要とする場合"something.h"
、コンパイルに追加する必要がある唯一のヘッダーにする必要があります。ヘッダーで宣言されていない必要な機能がある場合"something.h"
は、関連するヘッダーを含める必要があります。これは、たとえば<stddef.h>
、関数の 1 つが を使用するため、ヘッダーがインクルードされることを意味する場合があります。size_t
@quamranaが指摘しているように、適切な場合は構造体の前方宣言を使用できます(質問はCでタグ付けされており、C++ではないため、クラスではありません)。メンバーのいずれか。