問題タブ [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.

0 投票する
2 に答える
512 参照

c++ - pimpl-idiom を使用したライブラリの作成

pimpl-idiom を使用するライブラリのインターフェイスを定義しようとしています。以下は、私が定義する典型的なインターフェイス クラスです。

関数 func1()、func2() はインターフェース関数です。そして、notif1()、notif2() は、アプリケーションが (A のサブクラスで) 実装する必要がある通知関数です。

これは、ライブラリのインターフェイスを定義する正しい方法ですか? この方法に欠点はありますか、それともより良い解決策はありますか?


すべての答えをありがとう。したがって、私が収集したすべての回答から、ライブラリのインターフェイスを表すには、次の方法が適していることがわかります。

インターフェイス ライブラリはインターフェイス関数を実装し、アプリケーションは派生クラスで通知関数を実装します。このパターンに従うライブラリの良い例はありますか?

0 投票する
2 に答える
1261 参照

c++ - ピンプルのメソッドはインライン化されていますか?

次の簡単な例を考えてみましょう:

ヘッダー:

実装:

メイン:

質問は次
のとおりです。メソッドはA::Imp::fooにインライン化されA::fooますか?
そのメソッドの内容は実装に依存しますか?

PS私はgccを使用しています(問題がある場合は4.3.0)。

編集

うまく説明できていなかったと思います。私が正確に意味したのはこれです。最適化レベルを最大にした場合、 は または// do something and return the resultに配置されますA::foo()A::Imp::foo()?
最適化がなければ、これは行われていないことがわかります (the pimpl->foo()はまだ呼び出されています)。

A::foo() が main() でインライン化されることはないことは理解していますが、それは私が求めていることではありません。

0 投票する
5 に答える
955 参照

c++ - カプセル化に関するCodeCompleteからのC++アドバイス?

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

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

0 投票する
4 に答える
3247 参照

c++ - フレンド宣言なしの Pimpl イディオムと内部オブジェクト コラボレーション

pimpl イディオムを使用していくつかのクラスを実装していますが、いくつかの設計上の問題に遭遇しています。

まず、私はいつもニキビがこのように行われるのを見てきました

私はこのアプローチを使用するいくつかのクラスを持っていますが、私の問題は、これらのクラスのいくつかがお互いの実装の詳細にアクセスする必要があることですが、_pimpl ポインターはプライベートに宣言されています。

_pimpl public を宣言することのマイナス面を誰でも見ることができますか。明らかに、公開されている場合、誰かが誤って (または故意に) 再割り当てする可能性があります。(「プライベート」を「パブリック」として#定義して、とにかくアクセスを許可することができるという事実を無視しています。これを行うと、得られるものに値します)。

私のデザインに欠陥があるかもしれませんが、その点についてのコメントも歓迎します。

Object を完全に定義せずに Object::ObjectImpl を前方宣言することはできないため、友人を使用することは本当に嫌いです。

すなわち

Thxマーク。

* 更新 - 詳細 **

Command と呼ばれるクラスと Results と呼ばれるクラスの 2 つのクラスがあります。結果のベクトルを返す Command のメソッドがあります。

Command と Results はどちらも pimpl イディオムを使用します。リザルトへのインターフェースをできるだけ小さくしたい。

Command::getResults() に追加されました。ResultsImpl を結果に挿入します。Command::prepareResults() では、ResultsImpl にアクセスする必要があります。

M.

0 投票する
2 に答える
300 参照

c - 実装と pimpl-idiom を隠すための型キャスト構造体

私は、C では次のようになる pimpl-idiom について知っています。

ただし、型キャストを使用すると、不透明なポインターを取り除き、誰かが実装を台無しにする可能性を減らすことができます。

後者の場合、FooBar で操作を行う関数は、単純に FooBarImpl に型キャストして、「プライベート」メンバーへのアクセスを取得します。

たとえば、あるメンバーを FooBar に追加するが、FooBarImpl には同じことをしない場合、これがどのように問題になるかがわかります。ただし、私の場合、FooBar には 1 つのメンバーのみが含まれ、変更される可能性はほとんどありません。

これは良い習慣と見なされますか、それとも実装の詳細を非表示にしたい場合は pimpl-idiom に固執する必要がありますか?

ありがとうございました。

0 投票する
2 に答える
335 参照

c++ - PIMPL、POD、実装クラスの可視性、そのデストラクタは呼び出されますか?

ウィキペディアは、不透明なポインターに関する記事で、次のように主張しています。

dポインターは、クラスの唯一のプライベートデータメンバーであり、構造体のインスタンスを指します(構造体は表示されないため、PODである必要があります)。

これはPIMPLでは必須ではなく、ウィキペディアは一般的に特異なものですよね。

私は私の質問への答えとしてd-pointerタグの欠如をとっていますが、誰かがウィキペディアに貢献したり、物事を明確にしたりすることを望んでいます。または、ウィキペディアがひどい、最後の手段などだと言ってください:)

私の質問のポイントは、cpp実装ファイルで完全に宣言および定義されたときに、ネストされたクラスのメソッドがどの程度表示されるかということです。そのデストラクタは期待どおりに呼び出されますか(包含クラスはそのデストラクタでdeleteを呼び出します)?

_編集_ 修正バージョン、http://en.wikipedia.org/wiki/Opaque_pointer

0 投票する
5 に答える
1166 参照

c++ - テンプレート化されたクラスを使用した pimpl イディオムに利点はありますか?

pimpl イディオムの主な利点は、ヘッダーではなく実装ファイル内のデータ メンバーを非表示にすることです。ただし、コンパイラが必要に応じてテンプレートをインスタンス化できるようにするには、ヘッダーでテンプレートを完全に定義する必要があります。この場合、テンプレート化されたクラスに pimpl イディオムを使用する利点はありますか?

0 投票する
2 に答える
805 参照

c++ - pimpl イディオムの実装中のリンカー エラー

プロバイダーをもう少し明確に編集しました。皆様を混乱させて申し訳ありません。

これは Windows の下にあります。

pimpl イディオムを使用してクラスを実装する静的ライブラリがあります。pimpl ヘッダーは、消費するコードによって使用されるだけでなく、静的ライブラリにもリンクされます。それでも、消費コード (.exe) をコンパイルすると、リンカは、pimpl ヘッダーが隠していると思われる実装クラスの未解決の外部オブジェクトについて不平を言います。

これはどのように可能ですか?

Bar.exe をコンパイル/リンクすると、リンカは FooImpl を解決できないと文句を言います。今は仕事用の PC にアクセスできないので、正確に何を言っているのか忘れてしまいましたが、それが要点です。pimpl ルートに進む目的は、Bar.exe が FooImpl を気にする必要がないようにすることだったので、このエラーは私には意味がありませんでした。

正確なエラーは次のようになります。

1>Foo.lib(Foo.obj): エラー LNK2019: 未解決の外部シンボル "public: __thiscall FooImpl::FooImpl(void)" (??0FooImpl@@QAE@XZ) が関数 "public: __thiscall Foo::Foo で参照されています(無効)" (??0Foo@@QAE@XZ)

0 投票する
3 に答える
429 参照

c++ - C++ クラスで外部型が漏れないようにする

次のようにヘッダーで定義されたクラスがあります(省略):

cairo_t と cairo_surface_t は、Cairoグラフィックス ライブラリによって定義された型です。

私が抱えている問題は、このクラスまたは別のライブラリまたはアプリケーションから派生したクラスを使用する場合、CairoRenderer ヘッダーを介して cairo 型を「リーク」しているため、cairo ヘッダーも含める必要があることです。同じライブラリ内のこのクラス (またはそのサブクラス) を、cairo ヘッダーをインクルードしたり、cairo ライブラリにリンクしたりする必要なく、外部で使用できるようにしたいと考えています。

次に試したのは、ウィキペディアの例に従って pimpl 手法を使用することでした。達成したいことができるように見えたからです。

CairoRenderer.h (省略形)

CairoRenderer.cpp (省略形)

私が抱えている問題は、派生クラスから m_pimpl メンバーにアクセスしようとすると、コンパイラ エラーが発生することです。

私はにきびを間違っていますか?それとも私がやりたいことは可能ですか?

0 投票する
3 に答える
11090 参照

c++ - テンプレート化されたクラスの pimpl

ライブラリのユーザーが外部依存関係 (boost など) を必要としないように pimpl イディオムを使用したいのですが、メソッドがヘッダーにある必要があるため、クラスがテンプレート化されている場合は不可能に思えます。代わりに何かできることはありますか?