1. ホーム
  2. c++

[解決済み] PIMPLイディオムは実際に使われているのでしょうか?

2022-04-22 14:46:22

質問

私は本を読んでいます。 例外的なC++"。 Herb Sutter著、その本の中でPIMPLイディオムについて学びました。基本的には、このイディオムの構造は private オブジェクトの class に動的に割り当てる。 コンパイル時間の短縮 (そして、プライベートな実装をより良い方法で隠します)。

例えば

class X
{
private:
  C c;
  D d;
} ;

に変更することができる。

class X
{
private:
  struct XImpl;
  XImpl* pImpl;
};

と、.cppファイルで、定義しています。

struct X::XImpl
{
  C c;
  D d;
};

しかし、このようなアプローチは、私が働いてきた会社でも、ソースコードを見たことのあるオープンソースプロジェクトでも、これまで見たことがありません。では、この手法は実際に使われているのでしょうか?

どこでも使えるのか、それとも注意したほうがいいのか?また、この技術は組み込みシステム(性能が非常に重要な場所)で使用することが推奨されますか?

どのように解決するのですか?

<ブロッククオート

さて、このテクニックは実際に使われているのでしょうか?どこにでも使えるのか、それとも注意深く使うべきなのか?

もちろん、使われていますよ。私のプロジェクトでも、ほとんどすべての授業で使っています。


PIMPLイディオムを使用する理由。

バイナリ互換性

ライブラリを開発する場合、フィールドを追加/変更することで XImpl クライアントとのバイナリ互換性を壊すことなく(つまりクラッシュする!)。のバイナリレイアウトは X クラスに新しいフィールドを追加しても変更されません。 Ximpl クラスは、マイナーバージョンアップで新機能を追加しても問題ありません。

もちろん、新しいパブリック/プライベートな非仮想メソッドを X / XImpl バイナリ互換性を壊すことなく、標準的なヘッダー/実装のテクニックと同等になります。

データの隠蔽

ライブラリ、特にプロプライエタリなライブラリを開発している場合、ライブラリのパブリック・インターフェースを実装するために、どのような他のライブラリや実装技術が使われたかを開示しないことが望ましい場合があります。それは、知的財産権の問題であったり、ユーザが実装について危険な仮定をしたり、ひどいキャスティングのトリックを使ってカプセル化を破ったりしたくなるかもしれないと考えたりするからです。PIMPLはそれを解決/軽減してくれます。

コンパイル時間

のソース(実装)ファイルだけなので、コンパイル時間が短縮されます。 X にフィールドやメソッドを追加したり削除したりする際に、再構築する必要があります。 XImpl クラスは、標準的な手法ではプライベートフィールドやメソッドを追加することに対応します)。実際には、よくある操作です。

標準的なヘッダ/実装手法(PIMPLなし)の場合、新しいフィールドを X を割り当てるすべてのクライアントは X (スタック上でもヒープ上でも) アロケーションのサイズを調整する必要があるため、リコンパイルが必要です。さて、X を割り当てないクライアントはすべて また が必要ですが、これはオーバーヘッドにすぎません(クライアント側で得られるコードは同じです)。

さらに、標準的なヘッダーと実装の分離では XClient1.cpp は、プライベートメソッドであっても、再コンパイルが必要です。 X::foo() に追加されました。 XX.h が変更されたにもかかわらず XClient1.cpp はカプセル化の関係でこのメソッドを呼び出すことができないのです! 上記のように、これは純粋なオーバーヘッドであり、現実のC++ビルドシステムがどのように動作するかに関連しているのです。

もちろん、メソッドの実装を変更するだけなら再コンパイルは不要ですが(ヘッダに触れないので)、それは標準的なヘッダ/実装の手法と同等です。


<ブロッククオート

この技術は、組み込みシステム(パフォーマンスが非常に重要)に使用することが推奨されますか?

ターゲットがどの程度の性能なのかにもよりますが。しかし、この質問に対する唯一の答えは、あなたが何を得て、何を失うかを測定し、評価することです。また、顧客が組み込みシステムで使用することを意図したライブラリを公開していない場合、コンパイル時間の利点だけが適用されることを考慮してください。