2016-08-04 8 views
0

私は私のリファレンスのに対し、別の文脈では、古典的な「ポインタ」として「所有権」と「参照」に異なるタイプのshared_ptrを使用する方が良いでしょうか?

Reference<Type> m_someFoo

を所有しているオブジェクトのためのポインタのようなオブジェクトに

Ownership<Type> m_foo

を使用して対処したいと思いますは元のオブジェクトがもはや存在しないとき(例えばnullptrを返すことによって)知っているべきであり、さらに、元のオブジェクトが短時間の間削除されないようにする必要がありますロック)。

私はshared_ptrの(所有権)とのweak_ptr(参考)は同様の機能を提供することを知っています。しかし、をweak_ptrにロックし、raw ptrにアクセスするには、shared_ptrの作成に時間がかかります。また、raw ptrにアクセスする前に(例えば、オブジェクトが現在削除されていないことを知りながら)weak_ptrをロックしないようにすることはできません。

は、それは次のように所有リファレンスを実装するのが賢明です:

  • 所有はそのリファレンス S(例えばstd::list<Reference<Type>*>
  • 所有するオブジェクトが崩壊、これらのアドレスを知っています参照はnullptrに設定されています
  • リファレンスは、ロック時にuint m_lockCountで所有
  • にptrを含まm_lockCount++m_lockCount != 0

このソリューションは、いくつかのために特に実現可能だろうというとき所有m_lockCount--

  • のロックを解除するときにオブジェクトを解放することはできません参照インスタンスと高いアクセス率は、を参照してください。 sです。

  • +1

    "むしろ遅いshared_ptrの作成を伴います"。なぜそれが遅いのか分かりますか?所有されているオブジェクトが崩壊すると、これらの参照はnullptrに設定され、参照にはptrが所有権のm_lockCount、ロック時にはm_lockCount ++、ロック解除時にはm_lockCount--、所有権ではm_lockCount!= 0のときオブジェクトを解放できません。 また、思っているよりもはるかに速いと思います。 –

    +5

    あなたが書いたことは、まさに 'shared_ptr'と' weak_ptr'があなたのために設計されたものです。それらをそのまま使用し、手動で複製しないでください。 'weak_ptr'をロックすると新しい' shared_ptr'が作成されますが、元の 'share_ptr'からデータポインタを共有するので、その作成は速くなります。コピーされた' shared_ptr'が有効範囲外になるまで、refcountをインクリメントします。 refcountingの全ポイントは、ロックがアクティブなときに高速コピーであり、所有オブジェクトを解放しません。 –

    +2

    ホイールを再実装しないでください。 –

    答えて

    0

    あなたの提案された代替案は、参照へのバックポインタとしてstd::listを使用するという考えのために、shared_ptr/weak_ptrよりもはるかに遅くなります。単一のスレッドモードでしか動作しない場合は、追加のオーバーヘッドが発生します。スレッディングを追加すると、参照カウントと参照リストをアトミックに操作するためのロックが必要になります(ただし、リストを取得するとカウントは不要です)。 shared_ptr\weak_ptrは、オブジェクトに2つのポインタオーバーヘッドを追加し、最初のものよりも動的な割り当てはありません。

    +0

    所有権と参照をたくさん作成してコピーするときは、refcounting(shared/weak_ptrを参照)が最も高速です。しかし、ポインタのように動作するReferencesを頻繁に逆参照すると、上位アプローチが高速になります。あなたはロックで正しいです、私はリストのためにそれを必要とするでしょう。 – markusneg

    +0

    あなたの 'Reference'クラスが' Ownership'クラスが根底にあるポインタを解放するのを防ぐなら、 'shared_ptr'を使っている人とはどのように違いますか?それが真でない場合、 'Reference'を尊重したときにロックカウントを操作しなければなりません。それは' weak_ptr'と変わりません。 – nate

    +0

    リファレンスは、ロックがアクティブなときにオブジェクトが減衰するのを防ぎます。参照(おそらくスレッドセーフではないが高速)または条件付きインクリメント操作(スレッドセーフロックカウント増分)でptrに直接アクセスすることができます。後者は、shared_ptrからweak_ptrを作成するよりも速くなければなりません(もちろんこれはテストする必要があります)。 – markusneg

    関連する問題