2016-10-31 4 views
3

オブジェクトがオブジェクトの存続時間を気にする単一の親を持つ場合は、合成を使用します。同じ状況ではunique_ptrを使用しますが、オブジェクトはnullptrになります。タイプ「最短」のライフタイムを管理するにはどうすればよいですか?

複数の外部エンティティにオブジェクトが必要な場合は、shared_ptrを使用します。そのため、その外部エンティティの最後に興味がなくなるまで、その有効期間が延長されます。

ここで私は別の生涯の状況について質問したいと思います。 オブジェクトを生存させる必要がある場合は、最短での期間を使用しますか?

ここは例です。ファンクタを保存し、カウントが完了した後に実行するワンショットタイマを用意しましょう。現在

1. fulfilling its task - therefore it should be able to destroy istelf 

or 

2. the parent loosing interest in the timer - so the parent should be able to 
    destroy the object as well 

、私はユニークなポインタと厄介な実装を使用して:それは、このタイマーオブジェクトが後に破棄されていること、*私には意味があります。この問題の良いパターン/ガイドライン/実装は何でしょうか?

*の理由:1)ファンクターは、いくつかの他のリソース 2)タイマーは非常に大きな数に設定して、親が破棄された場合、私たちは一般に「ドン) 3放棄されている可能性を所有することができそのコールバックを呼び出すt

+0

これは、ネットワーク要求に応答して何かを計算するとスレッドキャンセルとよく似ていますが、接続が突然終了しました。コンピューティングを完了しても破損は発生しませんが、リソースの無駄です。 – curiousguy

答えて

0

実際のタイマーオブジェクトへの一意のポインタを持つラッパーオブジェクトと、破棄された場合はnullを返すタイマオブジェクトのゲッターを持つことをお勧めします。

このように、タイマーが満了して破棄された場合、興味を失っていない呼び出し元は、明らかに有効ではあるが実際に無効なポインタを保持したままになりません。

2

ここで深刻な並行性と再入可能性の問題があります。

2つ以上のビットのコードでポインタを削除する権利がある場合、どちらのコードでもそのポインタを間接的に参照解除することはできません。

同様に、所有権を持っているかどうかをチェックするブランチは、並行性がなくても、他の非ローカル(関数呼び出しなど)が実行されると失効する可能性があります。

これらを回避することができます。

template<class T> 
struct shared_destroyable { 
    std::shared_ptr<T> lock() const { 
    return atomic_load<T>(ptr.get()); 
    } 
    explicit operator bool() const { return (bool)lock; } 
    void reset(std::shared_ptr<T> pin = {}) { 
    atomic_store(ptr.get(), std::move(pin)); 
    } 
    shared_destroyable(std::shared_ptr<T> pin): 
    ptr(std::make_shared<std::shared_ptr<T>>(std::move(pin)) 
    {} 
    shared_destroyable()=default; 
    shared_destroyable(shared_destroyable&&)=default; 
    shared_destroyable(shared_destroyable const&)=default; 
    shared_destroyable& operator=(shared_destroyable&&)=default; 
    shared_destroyable& operator=(shared_destroyable const&)=default; 
private: 
    std::shared_ptr<std::shared_ptr<T>> ptr; 
}; 

これはweak_ptrshared_ptrハイブリッドのような漠然とした動作をします。

最後のものが消えた場合、オブジェクトは破棄されます。

しかし、それら.reset()のいずれかの場合、オブジェクトは、すぐlock()編があり、最後の他のコードは、その範囲を終了したとしてを破壊しています。

参照の変更。

if(auto sp = sd.lock()) { 
    // use sp 
} 

をしてsp寿命は、誰かが、別のスレッドでは、ブロック内のsd.reset()をした場合でも、{}の範囲を最後に保証されているか、あなたが呼び出すとき:

ので、使用時に、あなたはこれを行いますいくつかの他の方法。

関連する問題