6

コードコンプリートの「適切なカプセル化」のセクションでは、プライベート実装の詳細を非表示にすることをお勧めします。例はC++で与えられます。基本的には、クラスレベルでも、インターフェイスを実装から完全に分離するという考え方です。

class Employee {
public:
    ...
    Employee( ... );
    ...

    FullName GetName() const;
    String GetAddress() const;

private:
    EmployeeImplementation *m_implementation;
};

これは本当に時間の有効活用ですか?これは非効率的であるように見えるだけでなく(これによりどのようなパフォーマンスペナルティが発生しますか?)、コードコンプリート(「複雑さの管理」)のモットー全体が逆転したようです-これは複雑さを追加しませんか?

4

5 に答える 5

3

PIMPLイディオムのもう1つの利点は、ABIを維持することです。実際のPimplIdiomを参照してください。

クラスのサイズは一定のままです。これは、インターフェースをそのままにして、内部実装を変更できることを意味します。

実装がコンパイルされた形式(lib、dllなど)で配布されている場合、状況によっては、クラスを使用するコードを再コンパイルしなくても、ライブラリを置き換えることができる場合があります。したがって、パブリックインターフェイスが変更されない限り、コードを完全にスタンドアロンのモジュールとして分離します。

他の人が述べているように、コンパイル時間も短縮されます。これは、場合によっては十分な理由になる可能性があります。

于 2011-06-12T11:22:15.527 に答える
2

ヘッダーファイルにはパブリックメンバーとプライベート実装への単一のポインタのみが含まれるようになったため、カプセル化が増加します。

また、間接レベルが余分にあるため、(わずかに?)パフォーマンスが低下します。

ここで重要なのは「コンパイル時間を短縮する」ことです。

あなた(あなたの会社)がクラスの唯一のユーザーである場合、私はあなたがこのイディオムを使用する理由はないと思います。パフォーマンスが低下し、とにかくソースコードを毎日(または定期的に)再構築する必要があります(クラス間の依存関係に注意する必要があります)。

これは、クラスの唯一のコンシューマーである場合、コンパイル時間はほとんど関係ないはずであることを意味します。

ライブラリを配布している場合、話はまったく異なります。ヘッダーの変更は、クラスのプライベート部分を変更した場合でも、新しいバージョンを使用するためにアプリケーションを再構築する必要があることを意味します。ここでpimplイディオムを使用すると、ダイナミックライブラリのユーザーには変更が表示されなくなります。

于 2011-06-12T09:25:50.263 に答える
1

このイディオムは、貧弱なヘッダーを抽象化するために使用されますが、それ以外はあまり使用されません。クラスを定義するために必要なタイプに、マクロをリークしたり、コンパイルに時間がかかるなどのヘッダーが含まれている場合にのみ使用してください。それ以外は、通常、正しいこととは見なされません。とにかく実装には動的割り当てと参照セマンティクスが必要なので、それをインターフェイスにしCreateForMyPlatform()て、cppファイルに定義を持つメソッドを提供することもできます。少なくとも、そのシナリオではスマートポインターを使用できます。

于 2011-06-12T11:25:55.057 に答える
1

ポインタによる余分なレベルの間接化は、余分なキャッシュ ミスを引き起こし、プログラムの速度を低下させる可能性があります。私の知る限り、このイディオム(PIMPL)は、コンパイル時間を短縮するために最もよく提案されています。employee.h1 つのポインターではなく、クラス内のすべてのフィールドを持つヘッダーがあるとします。現在、従業員の詳細を変更するたびに(フィールドの追加または削除など)、すべてのファイルをemployee.h再コンパイルする必要があります。で定義された実装クラスへのポインタが 1 つしかない場合は、変更時にemployee.cppのみemployee.cpp再コンパイルする必要がありますEmployeeImplementation

では、コンパイル時間の短縮は追加コストに見合うものでしょうか? それを決めることができるのはあなただけです。

于 2011-06-12T06:09:20.410 に答える
1

pimpl イディオムの主な利点 (または少なくともその 1 つ) は、コンパイル時間を節約することではなく、コンポーネント間の疎結合、つまり依存関係の解消を可能にすることだと思います。

他の多くのコンポーネントが使用するインフラストラクチャ ライブラリを提供するとします。次に、@zvrba が示したように、プライベート実装の詳細を変更するたびに、すべてのクライアントを再コンパイルする必要があります。大したことではないかもしれませんが、大規模で複雑なプロジェクトでは、コンポーネント間の統合は複雑な作業になる場合があります。pimpl では、ライブラリが動的 (dll、.so) の場合、クライアントは何もする必要はありません。

于 2011-06-12T08:59:21.110 に答える