問題タブ [smart-pointers]

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 投票する
6 に答える
255 参照

c++ - A*をB*に自動的に変換する

クラスが与えられたとしましょうABそれへのポインタを小さなクラス、ある種のスマートポインタにラップしたいのですが、aB*が自動的にに変換されるという制約があるA*ため、すでにを使用しているコードを書き直す必要はありませんA*

したがってB、次のようにコンパイルするように変更したいと思います...

Bから継承することAはオプションではないことに注意してください(のインスタンスAは私の制御できない工場で作成されます)...

出来ますか?

ありがとう。

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

c++ - 従来の double ポインターの代わりに auto_ptr へのポインター

私はスマート ポインターを初めて使用し、既存のコードをリファクタリングして auto_ptr を使用しようとしていました。私が持っている質問は、それが理にかなっている場合、ダブルポインターとそれに相当する auto_ptr についてです。

ダブルポインターをパラメーターとして受け入れる関数があり、関数はそれにリソースを割り当てます。

この関数は、次のように使用されます。


delete を明示的に呼び出す必要がないように、auto_ptr を使用したいと考えています。以下は正しいですか?

その後

ありがとう。

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

c++ - boost::shared_ptr (または別のスマート ポインター) をオブジェクトの親の参照カウンターにアタッチする方法は?

以前にこの概念に遭遇したことを覚えていますが、今は Google で見つけることができません。

タイプ B のオブジェクトを直接埋め込むタイプ A のオブジェクトがある場合:

Bたとえば、へのスマート ポインターを取得するにはどうすればよいですか?boost::shared_ptr<B>の参照カウントを使用しますAか? Aそれ自体のインスタンスがヒープに割り当てられていると仮定すると、たとえばenable_shared_from_this.

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

c++ - 「新しい」のみで私のものから派生したクラスのオブジェクトを作成するようにユーザーに強制するにはどうすればよいですか?

参照カウントを実装するには、 のIUnknownようなインターフェイスとスマート ポインター テンプレート クラスを使用します。インターフェイスには、以下を含むすべての参照カウント メソッドの実装がありますRelease()

スマート ポインター テンプレート クラスには、生のポインターを受け入れるコピー コンストラクターと代入演算子があります。したがって、ユーザーは次のことができます。

そして、プログラムは未定義の動作を実行します。オブジェクトは参照カウント 0 で作成され、スマート ポインターが構築されて 1 にバンプされます。その後、関数が戻り、スマート ポインターが破棄され、スタックに割り当てられた変数が呼び出さRelease()れます。delete

ユーザーは次のこともできます。

また、で作成されていないオブジェクトnewdeleted です。最高の未定義の動作。

ユーザーが派生したすべてのオブジェクトを作成するためにIUnknownLike強制的に使用するようにインターフェイスを変更する方法はありますか?newIUnknownLike

0 投票する
6 に答える
2882 参照

c++ - スマートポインタに含まれているリソースの解放の失敗を処理するにはどうすればよいですか?

リソースを表すオブジェクトが共有ポインターに含まれている場合、リソースの割り当て解除中のエラーはどのように処理する必要がありますか?

編集1:

この質問をより具体的に言うと、多くのCスタイルのインターフェースには、リソースを割り当てる機能と、リソースを解放する機能があります。例としては、POSIXシステムのファイル記述子の場合はopen(2)とclose(2)、Xサーバーへの接続の場合はXOpenDisplayとXCloseDisplay、SQLiteデータベースへの接続の場合はsqlite3_openとsqlite3_closeがあります。

このようなインターフェイスをC++クラスにカプセル化し、Pimplイディオムを使用して実装の詳細を非表示にし、共有ポインターを返すファクトリメソッドを提供して、リソースへの参照が残っていないときにリソースの割り当てが解除されるようにします。

ただし、上記のすべての例および他の多くの例では、リソースの解放に使用された関数がエラーを報告する場合があります。この関数がデストラクタによって呼び出された場合、通常、デストラクタはスローしてはならないため、例外をスローすることはできません。

一方、リソースを解放するためのパブリックメソッドを提供する場合、2つの可能な状態を持つクラスがあります。1つはリソースが有効であり、もう1つはリソースがすでに解放されています。これはクラスの実装を複雑にするだけでなく、誤った使用法の可能性も開きます。インターフェイスは使用エラーを不可能にすることを目的としているため、これは悪いことです。

この問題について助けていただければ幸いです。

質問の元のステートメント、および可能な解決策についての考えは以下のとおりです。

編集2:

現在、この質問には報奨金があります。ソリューションは次の要件を満たす必要があります。

  1. リソースへの参照が残っていない場合にのみ、リソースが解放されます。
  2. リソースへの参照は明示的に破棄される可能性があります。リソースの解放中にエラーが発生した場合、例外がスローされます。
  3. すでにリリースされているリソースを使用することはできません。
  4. リソースの参照カウントと解放はスレッドセーフです。

ソリューション次の要件を満たす必要があります。

  1. これは、 boostC ++テクニカルレポート1(TR1)、および今後のC++標準であるC++0xによって提供される共有ポインターを使用します。
  2. それは一般的です。リソースクラスは、リソースの解放方法を実装するだけで済みます。

お手数をおかけしますが、よろしくお願いいたします。

編集3:

私の質問に答えてくれたみんなに感謝します。

アルスクの答えは、賞金で要求されたすべてを満たし、受け入れられました。マルチスレッドコードでは、このソリューションには個別のクリーンアップスレッドが必要になります。

別のクリーンアップスレッドを必要とせずに、クリーンアップ中の例外が実際にリソースを使用したスレッドによってスローされるという別の回答を追加しました。あなたがまだこの問題に興味を持っているなら(それは私をとても悩ませました)、コメントしてください。

スマートポインタは、リソースを安全に管理するための便利なツールです。このようなリソースの例としては、メモリ、ディスクファイル、データベース接続、またはネットワーク接続があります。

典型的なシナリオでは、リソースをカプセル化するクラスはコピー不可能でポリモーフィックである必要があります。これをサポートする良い方法は、共有ポインターを返すファクトリメソッドを提供し、すべてのコンストラクターを非公開として宣言することです。これで、共有ポインタを自由にコピーして割り当てることができます。オブジェクトへの参照がなくなると、オブジェクトは自動的に破棄され、デストラクタはリソースを解放します。

しかし、このアプローチには問題があります。デストラクタはスローしてはならないため、リソースの解放の失敗は検出されないままになります。

この問題を解決する一般的な方法は、リソースを解放するためのパブリックメソッドを追加することです。

残念ながら、このアプローチでは別の問題が発生します。オブジェクトには、すでにリリースされているリソースが含まれている可能性があります。これにより、リソースクラスの実装が複雑になります。さらに悪いことに、クラスのクライアントがそれを誤って使用する可能性があります。次の例はとてつもないように見えるかもしれませんが、マルチスレッドコードの一般的な落とし穴です。

オブジェクトが破棄される前にリソースが解放されないようにすることで、失敗したリソースの割り当て解除に対処する方法が失われます。または、オブジェクトの存続期間中にリソースを明示的に解放する方法を提供します。これにより、リソースクラスを誤って使用できるようになります。

このジレンマから抜け出す方法があります。ただし、解決策には、変更された共有ポインタークラスを使用することが含まれます。これらの変更は物議を醸す可能性があります。

boost :: shared_ptrなどの一般的な共有ポインタの実装では、オブジェクトのデストラクタが呼び出されたときに例外がスローされないようにする必要があります。一般に、デストラクタはスローしてはならないため、これは妥当な要件です。これらの実装では、オブジェクトへの参照が残っていない場合にデストラクタの代わりに呼び出されるカスタム削除関数を指定することもできます。スローなしの要件は、このカスタム削除機能に拡張されています。

この要件の論理的根拠は明らかです。共有ポインタのデストラクタはスローしてはなりません。削除関数がスローしない場合、または共有ポインターのデストラクタもスローしません。ただし、同じことが、リソースの割り当て解除につながる共有ポインターの他のメンバー関数にも当てはまります。たとえば、reset():リソースの割り当て解除が失敗した場合、例外をスローすることはできません。

ここで提案する解決策は、カスタム削除関数をスローできるようにすることです。これは、変更された共有ポインタのデストラクタが、deleter関数によってスローされた例外をキャッチする必要があることを意味します。一方、デストラクタ以外のメンバー関数(reset()など)は、デリータ関数の例外をキャッチしてはなりません(その実装はやや複雑になります)。

スロー削除関数を使用した元の例を次に示します。

これで、reset()を使用してリソースを明示的に解放できます。別のスレッドまたはプログラムの別の部分にリソースへの参照がまだある場合、reset()を呼び出すと、参照カウントがデクリメントされるだけです。これがリソースへの最後の参照である場合、リソースは解放されます。リソースの割り当て解除が失敗すると、例外がスローされます。

編集:

削除機能の完全な(ただしプラットフォームに依存する)実装は次のとおりです。

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

c++ - 非オブジェクト型のC++スマートポインタ?

auto_ptr、shared_ptr などのスマート ポインターを使用しようとしています。ただし、この状況での使用方法がわかりません。

よくわかりませんが、ストレージ変数は単に malloc されたメモリであり、C++ クラス オブジェクトではないと思います。ストレージ変数にスマート ポインターを使用する方法はありますか?

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

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

c++ - boostのweak_ptrから生のポインターを取得できますか?

boost :: weak_ptrから生のポインタを取得することは可能ですか?Boostのshared_ptrにはget()メソッドと"->"演算子があります。weak_ptrが同じ機能を持たない理由はありますか?

0 投票する
1 に答える
1911 参照

c++ - CComPtr CoCreateInstance は 0x80070582 を返します (クラスは既に存在します)。

ユーザーが [ログイン] ボタンを押したときに呼び出される StartComObjects 関数と、ユーザーが [キャンセル] ボタンを押したときに呼び出される StopComObjects 関数があります。StartComObjects 関数は、CComPtr.CoCreateInstance を使用して COM オブジェクトを作成し、AfxConnectionAdvise を使用していくつかのコネクション ポイントを設定します。ユーザーが [キャンセル] ボタンを押すと、接続ポイントは AfxConnectionUnadvise を使用して切断され、CComPtr で Release を呼び出す前に COM オブジェクトが停止されます。

ログイン ボタンをもう一度押すと、CComPtr.CoCreateInstance が 0x80070582 を返します (クラスは既に存在します)。これにより、StartComObjects の 2 回目の呼び出しで COM オブジェクトが作成されなくなります。なぜこれが機能しないのかわかりません。CComPtr::Release で COM オブジェクトを解放し、古いオブジェクトが停止された後に新しいオブジェクトを作成できるようにすべきではありませんか? これを回避する方法はありますか?

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

c++ - intrusive_ptr:なぜ共通ベースクラスが提供されないのですか?

boost::intrusive_ptrが必要intrusive_ptr_add_refでありintrusive_ptr_release、定義する必要があります。これを行う基本クラスが提供されないのはなぜですか?ここに例があります:http://lists.boost.org/Archives/boost/2004/06/66957.phpですが、ポスターには「これが必ずしも良い考えだとは思わない」と書かれています。なぜだめですか?

更新:このクラスが多重継承で誤用される可能性があるという事実は十分な理由ではないと思います。独自の参照カウントを持つ複数の基本クラスから派生するクラスでも、同じ問題が発生します。これらのrefcountが基本クラスを介して実装されているかどうかは、違いはありません。

マルチスレッドに問題はないと思います。boost::shared_ptrアトミック参照カウントを提供し、このクラスも可能です。

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

c++ - shared_ptrはどこにありますか?

shared_ptrがどこにあるかを見つけようとして数時間経った今、私はとてもイライラしています。私が見ている例のどれも、(そして機能している)ヘッダーを含めるための完全なコードを示していませんshared_ptr。単に述べるだけstdで、tr1まったく<memory>役に立たない!ブーストをダウンロードしましたが、それでも表示されません。誰かがそれを見つける場所を正確に伝えることによって私を助けることができますか?

欲求不満を解消させてくれてありがとう!

編集:タイトルが変更されたようです。申し訳ありません。それで...それはまた、shared_ptrが「C ++バージョン依存」であることが私には明らかではなかったためです->それが私の環境を述べなかった理由です->したがって、おそらく私がそれを見つけるのが非常に困難だった理由です。

私はMSVS2008に取り組んでいます。

編集2:理由はわかりませんが、shared_ptrを探している間、[memory]と[boost / tr1/memory.hpp]と[boost/tr1 / tr1 / memory]を含めていました。もちろん、できませんでした。 't。

すべての回答をありがとう。