それで、このテクニックが実際に実際に使用されているのだろうか?どこでも使用できますか、それとも注意して使用しますか?
もちろん使用しています。私のプロジェクトでは、ほとんどすべてのクラスで使用しています。
PIMPLイディオムを使用する理由:
バイナリ互換性
ライブラリを開発しているときXImpl
、クライアントとのバイナリ互換性を壊すことなくフィールドを追加/変更できます(これはクラッシュを意味します!)。X
クラスに新しいフィールドを追加しても、クラスのバイナリレイアウトは変更されないためXimpl
、マイナーバージョンの更新でライブラリに新しい機能を追加しても安全です。
もちろん、バイナリの互換性を損なうことなく、新しいパブリック/プライベート非仮想メソッドをX
/に追加することもできますがXImpl
、これは標準のヘッダー/実装手法と同等です。
データ非表示
ライブラリ、特にプロプライエタリなライブラリを開発している場合は、ライブラリのパブリックインターフェイスを実装するために使用された他のライブラリ/実装手法を開示しないことが望ましい場合があります。知的所有権の問題のためか、ユーザーが実装について危険な仮定をしたり、ひどいキャストトリックを使用してカプセル化を壊したりする可能性があると考えているためです。PIMPLはそれを解決/軽減します。
コンパイル時間
X
フィールドまたはメソッドXImpl
(あるいはその両方)をクラスに追加/削除するときに、標準の手法でプライベートフィールド/メソッドの追加にマップするときに、ソース(実装)ファイルのみを再構築する必要があるため、コンパイル時間が短縮されます。実際には、これは一般的な操作です。
標準ヘッダー/実装技術(PIMPLを使用しない)では、新しいフィールドをに追加すると、割り当てのサイズを調整する必要があるため、(スタックまたはヒープのいずれかで)X
割り当てるすべてのクライアントをX
再コンパイルする必要があります。まあ、Xを割り当てないすべてのクライアントも再コンパイルする必要がありますが、それはオーバーヘッドです(クライアント側の結果のコードは同じになります)。
さらに、カプセル化の理由でこのメソッドを呼び出すことができない場合でもXClient1.cpp
、プライベートメソッドX::foo()
が追加X
およびX.h
変更された場合でも、標準のヘッダーと実装の分離を再コンパイルする必要がXClient1.cpp
あります。上記のように、これは純粋なオーバーヘッドであり、実際のC ++ビルドシステムの動作に関連しています。
もちろん、メソッドの実装を変更するだけの場合(ヘッダーに触れないため)再コンパイルは必要ありませんが、標準のヘッダー/実装手法と同等です。
この手法は、(パフォーマンスが非常に重要な)組み込みシステムでの使用をお勧めしますか?
それはあなたのターゲットがどれほど強力であるかに依存します。ただし、この質問への唯一の答えは、次のとおりです。あなたが得るものと失うものを測定および評価します。また、クライアントが組み込みシステムで使用するためのライブラリを公開していない場合は、コンパイル時の利点のみが適用されることを考慮してください。
struct XImpl : public X
。それは私にとってより自然に感じます。私が見逃した他の問題はありますか?