30

現在ヘッダーのみのC++ ライブラリをいくつか作成しました。私のクラスのインターフェースと実装の両方が同じ.hppファイルに書かれています。

私は最近、この種のデザインはあまり良くないと考え始めました。

  1. ユーザーがライブラリをコンパイルして動的にリンクしたい場合、それはできません。
  2. コードの 1 行を変更するには、ライブラリに依存する既存のプロジェクトを完全に再コンパイルする必要があります。

私はヘッダーのみのライブラリの側面を本当に楽しんでいます#include.

両方の長所を活かすことは可能ですか? つまり、ユーザーがライブラリをどのように使用したいかを選択できるようにします。ばかげたコンパイル時間を避けるために「動的リンク モード」でライブラリに取り組み、パフォーマンスを最大化するために完成品を「ヘッダーのみモード」でリリースするので、開発もスピードアップします。

論理的な最初のステップは、インターフェイスと実装.hpp.inlファイルに分割することです。

とはいえ、先に進む方法はわかりません。多くのライブラリLIBRARY_APIが関数/クラス宣言の先頭にマクロを追加するのを見てきました.ユーザーが選択できるようにするために、おそらく同様のものが必要でしょうか?


「...の複数定義」エラーを回避するために、すべてのライブラリ関数にinlineキーワードのプレフィックスが付けられています。キーワードはファイル内のマクロに置き換えられると思いますか? マクロは、「ヘッダーのみモード」の場合は解決され、「動的リンク モード」の場合は何も解決されません。LIBRARY_INLINE.inlinline

4

7 に答える 7

5

これは、オペレーティング システムとコンパイラ固有のものです。ごく最近のGCCコンパイラ (バージョン 4.9) を搭載した Linux では、プロシージャ間のリンク時最適化を使用して静的ライブラリを生成する場合があります。

これは、g++ -O2 -fltoコンパイル時とライブラリ リンク時の両方でライブラリをビルドg++ -O2 -fltoし、呼び出しプログラムのコンパイル時とリンク時の両方でライブラリを使用することを意味します。

于 2014-09-01T13:32:28.290 に答える
2

根拠

コンパイル時の依存関係と長いコンパイル時間というまさにその理由により、ヘッダーファイルには必要最小限、ライブラリモジュールにはできるだけ多く入れてください。ヘッダーのみのモジュールを使用する正当な理由は次のとおりです。

  1. ユーザー定義のテンプレート パラメーターの汎用テンプレート。

  2. インライン化が重要なパフォーマンスを提供する場合、非常に短い便利な関数。

ケース 1 では、多くの場合、.cpp ファイル内のユーザー定義型に依存しない一部の機能を非表示にすることができます。

結論

この理論的根拠に固執する場合、選択の余地はありません。ユーザー定義型を許可する必要があるテンプレート化された機能は、プリコンパイルできず、ヘッダーのみの実装が必要です。他の機能は、実装の詳細にさらされることを避けるために、ライブラリ内のユーザーから隠されている必要があります。

于 2014-09-06T09:49:53.343 に答える
1

動的ライブラリではなく、プリコンパイルされた静的ライブラリとシン ヘッダー ファイルを使用できます。インタラクティブなクイック ビルドでは、実装の詳細が変更された場合に、ワールドを再コンパイルする必要がないという利点があります。しかし、完全に最適化されたリリース ビルドでは、グローバルな最適化を行うことができ、それでも関数をインライン化できることがわかります。基本的に、「リンク時のコード生成」を使用すると、ツールセットはあなたが考えていたトリックを実行します。

私はMicrosoftのコンパイラに精通しており、Visual Studio 2010の時点で(それ以前ではないにしても)これを確実に行うことを知っています。

于 2014-09-08T19:20:51.537 に答える