最終更新:2026-10-12
C++ Pimpl イディオム¶
「実装へのポインタ」または「pImpl」は C++ のプログラミングテクニックであり、クラスの実装の詳細をオブジェクト表現から取り除いて別のクラスに移し、不透明なポインタを通じてアクセスします。
pImplイディオムを使用する理由は次のとおりです:
次の例を考えてみましょう:
pImplにすると次のようになります
CPPでの定義:
- バイナリ互換性
ライブラリを開発する際、クライアントとのバイナリ互換性を壊すことなくXImplにフィールドを追加・変更できます(壊せばクラッシュします!)。Ximplクラスに新しいフィールドを追加してもXクラスのバイナリレイアウトは変わらないため、マイナーバージョンの更新でライブラリに新機能を安全に追加できます。
もちろん、バイナリ互換性を壊さずにX / XImplに新しい公開・非公開の非仮想メソッドを追加することもできますが、これは標準的なヘッダ/実装の技術と同等です。
- データの隠蔽
ライブラリ、特にプロプライエタリなライブラリを開発している場合、そのライブラリの公開インターフェースを実装するために使われた他のライブラリや実装技術を公開したくないことがあるでしょう。それは知的財産の問題からであったり、ユーザーが実装について危険な仮定をしたり、恐ろしいキャストのテクニックでカプセル化を破壊するかもしれないと考えるからであったりします。PIMPLはこの難問を解決・緩和します。
- コンパイル時間
XImplクラスにフィールドやメソッドを追加・削除するとき(標準技術における非公開フィールド/メソッドの追加に相当します)、再ビルドが必要なのはXのソース(実装)ファイルだけなので、コンパイル時間が削減されます。実際、これはよく行われる操作です。
標準的なヘッダ/実装の技術(PIMPLなし)では、Xに新しいフィールドを追加すると、かつてXを(スタック上またはヒープ上に)再確保したすべてのクライアントが再コンパイルが必要になります。確保するサイズを調整しなければならないからです。もちろん、Xを一度も確保していないクライアントもすべて再コンパイルが必要ですが、それは単なるオーバーヘッドです(クライアント上の生成コードは同じです)。
https://stackoverflow.com/questions/8972588/is-the-pimpl-idiom-really-used-in-practices
関連トピック¶
- C++ デフォルトコンストラクタの回避 | C++那些事
- C++ クラス初期化リストイディオム | C++那些事
- C++ 関数テンプレートよりクラステンプレート | C++那些事
- C++ copy-and-swap イディオム | C++那些事
- C++ 依存性注入 | C++那些事
- C++ enum class 強い型付けされた列挙 | C++那些事
- C++ Header-Only と実装分離 | C++那些事
- C++ 遅延評価イディオム | C++那些事
- C++ ルックアップテーブル法イディオム | C++那些事
- C++ メンバポインタと型情報 | C++那些事