7

したがって、私は boost::shared_ptr を使用して、それが提供するさまざまな参照カウントの利点をすべて提供します。初心者向けの参照カウントはもちろんですが、コピー、割り当て、および STL コンテナーへの保存も可能です。

問題は、それを 1 つの「悪意のある」関数またはオブジェクトに渡すと、そのオブジェクトが ptr を保存できるため、外部関数またはオブジェクトがその所有権を適切に放棄しない限り、その割り当てを解除できないことです。

最終的に、私はオブジェクトの所有権を明示的に保つようにしています。これを実現するには、所有者にオブジェクトへの shared_ptr のみを保持させ、「ゲスト」オブジェクトはそのオブジェクトへの weak_ptr のみを保存します。

私は本当にshared_ptrの「共有」部分を望んでいませんが、weak_ptrsを作成するにはshared_ptrを使用する必要があります。scoped_ptrを使いたいのですが、コピーできないので非常に限られています。コンテナーに格納することも、weak_ptrs を貸し出すことも、新しいマネージャーに所有権を譲渡することもできません。

解決策は何ですか?

4

6 に答える 6

10

プライベートにして、必要な操作を行うためのファサードを提供します。誰もポインタを見ることはありません。その時点で、shared_ptr さえ必要ないと思います。

于 2010-04-22T02:28:10.023 に答える
3

Don't pass around the boost::shared_ptr object... even if you store the object, internally, using a boost::shared_ptr, you should make sure that functions take your object by constant reference rather than a copy of the shared pointer. Since you would need to dereference the shared pointer in order to pass the object to a function that passes by const reference, you will know whether it follows that protocol or not.

于 2010-04-22T03:20:26.707 に答える
1

質問で説明したように、ゲスト オブジェクトに weak_ptr を使用するだけで十分です。そうしないと、デッド ポインターの問題が発生します。

「悪意のある」機能/オブジェクトを削除するか、少なくともそれらの動作を修正するために、アプリケーションの再設計を行うことを検討します。

于 2010-04-22T02:45:08.347 に答える
0

その所有者/所有者のパラダイムでオブジェクトを処理したい場合は、Qtのようなことを行うことをお勧めします。

  1. システム内のすべてのクラスが継承する基本クラスオブジェクトを作成します。各オブジェクトは、その親/所有者と子を追跡します。
  2. setOwner(Object * owner)メソッドを使用して所有者を設定し、そのメソッドで所有者オブジェクトに新しい子について通知されるようにします。
  3. Objectのデストラクタは、破棄されたときにすべての子オブジェクトを削除する必要があります。
  4. Objectサブクラスへのスマートポインターを定義するテンプレートクラスを定義します。オブジェクトが破壊されたときに値がNULLになるように、オブジェクトが接続されたスマートポインタにその破壊について通知するようにします。

注意事項:

  1. オブジェクトデストラクタがオブジェクトの割り当てを正しく解除するには、すべてのオブジェクトをnewを介して割り当てる必要があります。
  2. オブジェクトの親を設定するのを忘れると、リークします
  3. Objectから継承しないオブジェクトの処理には注意が必要ですが、Objectから継承してオブジェクトを保持するテンプレートクラスを定義することで処理できます。
于 2010-04-22T03:27:42.093 に答える
0

There's really no good solution for what you're describing.

You can't use auto_ptr because you're not transferring ownership.

If you can guarantee the owner outlives the references, I'd recommend using a scoped_ptr/store by value in the owner and then passing a raw pointer or reference to those that need it.

If references can outlive the owner (and the references need to be gracefully notified), you have to use shared_ptr/weak_ptr. But, as you stated, you cannot prevent any class/function from locking the weak_ptr and "preventing" deallocation. But, in the interface, do not pass the shared_ptr, pass the weak_ptr. It's only as strong as a convention, but it says "don't hold onto this, it may go away".

于 2010-04-22T03:22:27.307 に答える
0

shared_ptr ブースト クラスを拡張し、delete をオーバーライドしてポインターを強制的に削除することができます。

問題は、ライブラリが shared_ptr を解放または解放していない場合、しばらくの間それを参照する可能性があるということです。この時点で、アプリケーションは SIGSEGV で失敗します。

共有ポインタの目的を完全に無効にしていると思います。

最善の解決策は、ライブラリを修正することです。

他の解決策として、呼び出しているライブラリ関数の終了時に AOP を使用してポインターを削除します。これはまだ壊れそうです。

于 2010-04-22T03:10:06.290 に答える