2013-07-08 11 views
9

std::shared_ptrstd::weak_ptrを使用してオブジェクトをジャグリングしようとしています。このシナリオは次のようなものです:shared_ptr&weak_ptr conversions

私はクラスchannelのオブジェクトを抽象クラスabstract::channel(純粋な仮想関数を使用しています)から派生させています。私はコンテナchannelContainerstd::vector)に、共有ポインタ(std::shared_ptr)〜channelオブジェクトを含んでいます。

ここでは、のオブジェクトのそれぞれにウィークポインタ(std::weak_ptr)を含む​​があります。このdequeの名前をfreeChannelQueueにします。

はそう言うことができます:「?どのように弱いポインタをオブジェクトへの参照を変換する」

std::vector<std::shared_ptr<abstract::channel> > channelContainer; 
std::deque<std::weak_ptr<abstract::channel > > freeChannelQueue; 

//Assuming that both the containers are filled appropriately How do I go about implementeing the below functions? 

abstract::channel& get_free_channel() { 
    //This should return a free channel object from 'freeChannelQueue' and pop the queue. 
} 

bool release_channel(abstract::channel& ch) { 
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue' 
} 

は、私が特に興味を持っています

+0

AFAIKオブジェクトまたはオブジェクト参照から 'weak_ptr'を直接初期化/構築することはできません。参照するオブジェクトは' shared_ptr'によって所有されている必要があります。したがって、構築のために 'shared_ptr'または' weak_ptr'が必要です。 – Piotr99

答えて

1

これはあなたのデザインですか?つまり、チャネルの生涯に重大な問題があります。たとえば、コードでget_free_channel()が呼び出された場合、宣言によってオブジェクトへの参照が返されますが、その使用期間を保証する方法はありません。 ...

std::shared_ptr<abstract::channel> get_free_channel() 
{ 
    // return free channel from 'freeChannelQueue' and pop the queue 

    // take a scoped lock on the free queue if necessary 

    while (!freeChannelQueue.empty()) 
    { 
     auto p_channel = freeChannelQueue.back(); 
     freeChannelQueue.pop_back(); 
     std::shared_ptr<abstract::channel> p = p_channel.lock(); 
     if (p) return p; 
    } 

    // freeChannelQueue empty... throw or return nullptr etc.. 
} 

については「リリース」:それクライアントコードは、あなたがから関数を呼び出していることが何であるかに応じて、重要ではないかもしれませんが、あなたは、おそらくのように、shared_ptrを返すようにしたいです

bool release_channel(abstract::channel& ch) { 
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue' 
} 

これは、channelContainerを検索してオブジェクトを検索し、そこからweak_ptrまたはshared_ptrを取得する場合にのみ可能です。再び - それはshared_ptrまたは直接weak_ptrを受けるので、あなたはおそらくプロトタイプを変更する必要があり、無料のキューは、その後に....すべてのすべてで

スマートポインタを押してロックし、それが道を理解せずに、あなたに有益な助言を与えることは難しいですあなたのチャネルのライフタイムを管理し、さまざまなスレッドがオブジェクトやキューをどのように使用しようとしているかを調べます。より正確な質問をしても、上記のことが少し助けてくれることを願っています。

+0

答えをありがとう、今のところ私は私の問題の答えを得た。デザインについてまだ分かりませんが、現在のデザインが自分のニーズに合っていないとわかった場合、質問が更新されます。 – user2559933

+0

@ user2559933:確かに...それに幸運。 –

+0

基本クラスとしてstd :: enable_shared_from_thisを追加すると、生ポインタまたは参照をshared_ptrに変換できます。抽象クラスにshared_ptrを返すメンバ関数を与えることができます。 – Dennis

3

あなたは

がちょうど割り当て= 例えばを使用して、共有ポインタから弱いポインタを作ることができる弱いポインタをオブジェクトへの参照を変換することはできません

std::shared_ptr<abstract::channel> get_free_channel(); 

その後、

bool release_channel(std::shared_ptr<abstract::channel> ch) 
{ 
    std::weak_ptr<abstract::channel> weak_ch = ch; 
    //... 
} 

寿命に気をつけて - shared_ptrのは、それらを指し示す弱いポインタの前に行くのだろうか?

0

私はあなたの質問をすべて理解しています。すべてのチャンネルオブジェクトを保持するコンテナがあり、アプリケーションで使用できるチャンネルの順序を維持するための2番目のコンテナがあります。次に、クライアントの次の空きチャネルへの参照を返すインターフェイスが必要になります。クライアントが終了すると、チャネルはコンテナに戻されます。

チャネルへの参照を取得するには、lockを使用してweak_ptrからshared_ptrを作成し、それを逆参照してください(元のオブジェクトを削除しないでください)。しかし、私は別の方法を実行する賢明な方法が表示されません、一致するオブジェクトのチャネルコンテナを検索し、再び一致するshared_ptrから弱いポインタを作成する必要があります。

私はweak_ptrと参照をまったく使用しないと考えていますが、shared_ptrを使用してください。 dequeを使ってどのチャネルを利用できるかを維持するので、代わりに使用可能なshared_ptrをそのまま使用することができます。終了時にクライアントが常にチャンネルをリリースすることに満足している場合は、すべてのオブジェクトのコンテナは必要なく、無料のチャンネルの両端キューのみが必要です。

他の人からも言われているように、チャンネルオブジェクトのライフタイムとクライアントでの使用方法を考慮する必要があります。

関連する問題