web-dev-qa-db-ja.com

ライブラリの設計:共通のヘッダーファイルまたは複数のヘッダーを提供する

最終的なヘッダーファイルのインクルードの設計に関して、本質的に2つのライブラリデザイナーの陣営があります。

  • パブリックAPIを構成する他のすべてのヘッダーファイルを含む単一のヘッダーファイルを提供します。たとえば、GTK +は gtk.h のみが含まれるように指示します。これはしないということは、すべてがその共通のヘッダーファイルに明示的に書き込まれることを意味します。
  • ユーザーが最も関心のある機能を持つヘッダーファイルをインクルードします。最も顕著な例は、I/Oの場合はstdio.h、文字列操作の場合はstring.hを含める必要がある標準ライブラリです。一般的なstd.hの代わりに

優先する方法はありますか? libabc はその点についてアドバイスを提供しませんが、同様の question への回答はそれらを分離しておくことを提案しますが、理由を特定しません。

7
matthias

一般にデザインは常に " 矛盾する目標のバランスをとる技術 "です。

ここでは、これらの目標があります。

  1. フレームワークは簡単に使用できる必要があります。 APIが15のヘッダーファイルである場合、ユーザーはどのファイルを含め、どのファイルを省略するかを常に苦労します。
  2. すべての一般的な機能は、単一のヘッダーファイルにある必要があります。そのため、ファイルI/Oをstring.hに含めることはできませんが、3 string.hヘッダーファイルも必要ありません。
  3. 依存関係は悪いので、可能な限り最小に減らしたい
  4. 大量の(大量の)ヘッダーファイルの読み取りが遅い
  5. ヘッダーファイルの各機能により、コンパイルするために別のヘッダーファイルを含める必要があるというリスクが生じます。

gtk.hは、アプリケーションのユーザーインターフェイスを構築する必要があるため、意味があります(ポイント#2)。各ウィジェットを個別に含める必要があると主張することもできますが、その場合、フレームワークの使用が少し難しくなります(ポイント#1)。

古いX11/Motifコードを見ると、eachCソースファイルの上部に数十の#includeステートメントが表示されます。コンパイルは少し速くなりますが、これらのリストを維持するには何時間もの手作業が必要です。

OTOH、ヘッダーファイルにあまりにも多くの機能を入れると、そこにあまりにも多くの依存関係があり、それらの1つがあなたを殺すかもしれません(たとえば、この依存関係が特定のバージョンの別のフレームワークを必要とするとき-> dependency hell )。

解決策がないことを今までにご理解いただければ幸いです。問題は複雑すぎて、新しいフレームワークが開始されるたびに再度対処する必要があります。

[〜#〜]編集[〜#〜]

しかし、その場合、GTK +が マクロチェック を介して単一のヘッダーを含めることを積極的に禁止するかなり良い理由があるはずです。 –マティアス

GTKの場合、#includeステートメントはパブリックAPIの一部です。これらのマクロを使用すると、ヘッダーファイル、その内容、名前、インクルードの順序を、1つの既存のプロジェクトを壊すことなくいつでも好きなように自由に再配置できます。

9
Aaron Digulla

すべてのヘッダーを1つのシングルに含めることはすばらしいことであり、他のユーザーが別のヘッダーを含めるよりも1つの単一のヘッダーを含めるほうが簡単です。

この種の設計の1つの問題であるwindows.hgtk.hなどの大きなヘッダーでは、window.hに比べて依然として小さいため、ビルドプロセスが遅くなる可能性があります。 windows.hでは、WIN32_LEAN_AND_MEANを定義してWindowsソケットや暗号化APIなどの一部の一般的でないヘッダーを除外してビルドプロセスを高速化することでこの問題を回避します。詳細はこちら Windowsヘッダーの使用

また、ライブラリが大きくなる頃には、ヘッダーが多く、扱いにくい場合があります。下位互換性を壊さないように、多くのマクロ、ロット、複雑なヘッダーを作成する必要があります。

とはいえ、私は個人的には単一ヘッダーのデザインを好みます。

2
user76452