問題タブ [pimpl-idiom]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - なぜ「PIMPL」イディオムを使用する必要があるのですか?
バックグラウンダー:
PIMPLイディオム(Pointer to IMPLementation) は、パブリック クラスがその一部であるライブラリの外では見ることができない構造またはクラスをパブリック クラスがラップする実装隠蔽の手法です。
これにより、内部実装の詳細とデータがライブラリのユーザーから隠されます。
このイディオムを実装するとき、パブリック クラス メソッドの実装はライブラリにコンパイルされ、ユーザーはヘッダー ファイルしか持っていないため、パブリック クラスではなく pimpl クラスにパブリック メソッドを配置するのはなぜですか?
説明のために、このコードはPurr()
実装を impl クラスに置き、それもラップします。
パブリック クラスに Purr を直接実装してみませんか?
c++ - C++ は pimpl イディオムを回避できなかったのでしょうか?
私が理解しているように、pimpl イディオムが存在するのは、C++ がすべてのプライベート クラス メンバーをヘッダーに配置することを強制するためだけです。ヘッダーにパブリック インターフェイスのみが含まれている場合、理論的には、クラスの実装を変更しても、プログラムの残りの部分を再コンパイルする必要はありません。
私が知りたいのは、C++ がそのような利便性を考慮して設計されていない理由です。クラスの非公開部分をヘッダーに公然と表示する必要があるのはなぜですか (しゃれは意図されていません)。
c++-cli - C++/CLI で PIMPL イディオムを使用する場合の MSVC++ リンカの警告
C++/CLI (バージョン 9.0) を使用して .NET アセンブリを作成しています。PIMPL イディオムを使用して、パブリック ヘッダーに不要なものを入れないようにしたいと考えています。残念ながら、クラスを前方宣言して追跡ハンドルを使用しようとすると、リンカー警告 4248 が表示されます。
警告 LNK4248: 'MyNamespace.PrivateClass' の未解決の typeref トークン (0100000E); イメージが実行されない場合があります
これは、実装クラスに CLI クラスを使用する場合でも、ネイティブ クラスを使用する場合でも同じようです。
コード例を以下に示します。
残念ながら、警告に関する Microsoft の説明はあまり有益ではありません。
c++ - C++でabstract(?)pimplのデバッグ情報を取得するには?
その作業を pimpl に委任するラッパー クラスがあり、pimpl は、いくつかの異なる方法で特殊化されたデータのない基本クラス/インターフェイスへのポインターです。
このような:
現在、これはほとんどの場合うまく機能しますが、デバッガーに入ると、派生クラスの x、y を表示できません (何でもかまいません)。通常、これは関係ありませんが、何か問題が発生したときに Derived の状態を確認することは重要ですが、pimpl は状態を覆い隠しすぎます (ただし、pimpl の元のアイデアなので、文句を言うことはできないと思います)。
現在、デバッグ目的で状態を出力する tostring() 関数がありますが、特に VisualStudio でこの種の構造をデバッグするためのより良い解決策があるかどうか疑問に思っていましたが、一般的な解決策の方が良いでしょう。
ありがとう
c++ - Pimpl イディオムと純粋な仮想クラス インターフェイス
プログラマーが Pimpl のイディオムまたは純粋な仮想クラスと継承のいずれかを選択する理由は何だろうと思っていました。
pimpl イディオムには、パブリック メソッドごとに 1 つの明示的な追加の間接化と、オブジェクト作成のオーバーヘッドが伴うことを理解しています。
一方、純粋な仮想クラスには、継承する実装のための暗黙の間接化(vtable)が付属しており、オブジェクト作成のオーバーヘッドがないことを理解しています。
編集:ただし、外部からオブジェクトを作成する場合はファクトリが必要です
pimpl イディオムよりも純粋仮想クラスが望ましくない理由は何ですか?
c++ - 実際のPimplIdiom
SOについては、pimplイディオムについていくつか質問がありますが、実際にどのくらいの頻度で活用されているかについては、もっと興味があります。
パフォーマンスとカプセル化の間にはいくつかのトレードオフがあることを理解しています。さらに、余分なリダイレクトによるデバッグの煩わしさもあります。
それで、これはクラスごとに採用されるべきものですか、それともオールオアナッシングベースですか?これはベストプラクティスですか、それとも個人的な好みですか?
それはやや主観的だと思いますので、私の最優先事項を挙げさせてください。
- コードの明確さ
- コードの保守性
- パフォーマンス
ある時点でコードをライブラリとして公開する必要があると常に想定しているので、それも考慮事項です。
編集:同じことを達成するための他のオプションは歓迎すべき提案です。
c++ - C++ でインターフェイスと実装を切り離すために使用するパターンは何ですか?
大規模な C++ プロジェクトでの問題の 1 つは、ビルド時間です。依存関係ツリーの上位に作業が必要なクラスがいくつかありますが、通常は、すべてのビルドに非常に長い時間がかかるため、作業を避けます。必ずしもパブリック インターフェイスを変更する必要はありませんが、プライベート メンバーを変更する必要がある場合があります (キャッシュ変数の追加、プライベート メソッドの抽出など)。あなたが直面している問題は、C++ ではプライベート メンバーでさえパブリック ヘッダー ファイルで宣言されているため、ビルド システムですべてを再コンパイルする必要があることです。
この状況であなたは何をしますか?
私が知っている2つの解決策をスケッチしましたが、どちらにも欠点があり、まだ考えていないより良い解決策があるかもしれません.
c++ - pimplイディオムとテンプレートクラスの友達
pimplイディオムを使用して、汚れたテンプレートコードを非表示にしようとしていますが、bodyクラスのフレンドの派生クラスにハンドルクラスへのアクセスを許可できません。MSVC9sp1からエラーC2248が発生します。エラーを複製するためのコードは次のとおりです。
助けていただければ幸いです。私の質問から明らかでない場合は、ユーザーから実装を隠そうとしてinterface::body
います。specific_body
interface
c++ - C++ クラスの pimpl'ing を自動化 -- 簡単な方法はありますか?
Pimpl は、多くの C++ コードのボイラープレートのソースです。それらは、マクロ、テンプレート、およびおそらく外部ツールの助けを少し組み合わせることで解決できるようなものに思えますが、最も簡単な方法が何であるかはわかりません. 持ち上げるのに役立つテンプレートを見てきましたが、それほど多くはありません。ラップしようとしているクラスのすべてのメソッドに対して転送関数を記述する必要があります。もっと簡単な方法はありますか?
make プロセスの一部として使用されるツールを想像しています。パブリックヘッダーを pimpl 化されたクラスにしたいので、ラップしたいクラス (pimpl 化されていない実装済み) をリストする pimpl.in などの入力ファイルを提供すると、そのファイルが調べられます。 pimpl クラスが生成され、'make install' 中にそれらのヘッダー (元のクラスのヘッダーではない) のみがインストールされます。問題は、本格的な C++ パーサーなしでこれを行う方法が見当たらないことです。外部ツールの仕事を簡単にする方法でクラスを書くことができるかもしれませんが、あらゆる種類のコーナーケース (テンプレート化されたクラスやテンプレート化されたメンバー関数など) を見逃すことになると確信しています。
何か案は?他の誰かがこの問題の解決策をすでに持っていますか?