すべてをヘッダーファイルだけに保持することが不可能なような依存関係のパターンはありますか?ヘッダーごとに1つのクラスのルールのみを適用した場合はどうなりますか?
この質問の目的のために、静的なものを無視しましょう:)
すべてをヘッダーファイルだけに保持することが不可能なような依存関係のパターンはありますか?ヘッダーごとに1つのクラスのルールのみを適用した場合はどうなりますか?
この質問の目的のために、静的なものを無視しましょう:)
すでに述べた静的なものを除いて、標準のC ++には機能がないことを認識しています。これには、(ヘッダーだけでなく)完全な変換単位を定義するためのライブラリが必要です。ただし、これを行うことはお勧めしません。そうすると、ライブラリが変更されるたびに、すべてのクライアントにコードベース全体を再コンパイルするように強制するためです。ソースファイル、静的ライブラリ、または動的ライブラリ形式の配布を使用している場合は、全員に再コンパイルを強制することなく、ライブラリを変更/更新/変更できます。
多くの言語機能を使用しないという明白な条件で、可能です。お気づきのとおり、static
キーワードをいくつか使用します。
いくつかのトリックが必要になる場合がありますが、確認することができます。
()
)。C ++ 0xでは、これが推奨される方法になることに注意してください。これは、初期化順序の大失敗から保護しながらスレッドセーフであることが保証されているためです。それまでは、スレッドセーフではありません;)これらの3つのポイントを尊重すると、本格的なヘッダーのみのライブラリを作成できると思います(私が見逃したものを誰かが見たことがありますか?)
多くのBoostライブラリは、コードが完全にテンプレートではなかったとしても、同様のトリックを使用してヘッダーのみになっています。たとえば、Asio
非常に意識的に行い、フラグを使用した代替案を提案します(Asio 1.4.6のリリースノートを参照)。
このように(ライブラリ開発者の側でもう少し努力することを犠牲にして)、クライアントはケーキを手に入れてそれも食べます。それは私が思うにかなり素晴らしい解決策です。
注:関数をインライン化できるかどうか疑問に思っstatic
ています。匿名の名前空間を自分で使用することを好むので、実際に調べたことはありません...
ヘッダールールごとに1つのクラスは無意味です。これが機能しない場合:
#include <header1>
#include <header2>
次に、これのいくつかのバリエーションは次のようになります。
#include <header1a>
#include <header2>
#include <header1b>
これにより、ヘッダーごとに1クラス未満になる可能性がありますが、いつでも(void *)とキャストおよびインライン関数を使用できます(この場合、「インライン」はコンパイラーによって適切に無視される可能性があります)。したがって、質問は、私には、次のように減らすことができます。
class A
{
// ...
void *pimpl;
}
プライベート実装pimplがAの宣言に依存している可能性はありますか?その場合、pimpl.cpp(ヘッダーとして)はAhの前後の両方である必要がありますが、いつでも(void *)を使用して、先行するヘッダーで関数をキャストおよびインライン化できるため、これを実行できます。
もちろん、私は間違っている可能性があります。どちらの場合でも:Ick。
私の長いキャリアの中で、ヘッダーのみの実装を許可しない依存関係パターンに出くわしたことはありません。
クラス間に循環依存関係がある場合は、抽象インターフェース(具体的な実装パラダイム)に頼るか、テンプレートを使用する必要があることに注意してください(テンプレートを使用すると、後でインスタンス化中に解決されるテンプレートパラメーターのプロパティ/メソッドを前方参照できます)。
これは、常にヘッダーのみのライブラリを目指すべきであるという意味ではありません。そのままで、テンプレートとインラインコードに予約する必要があります。それらは実質的な複雑な計算を含むべきではありません。