2

コードで shared_ptr と weak_ptr を使用する方法を見つけようとしています。クラス 1 とクラス 2 の 2 つのクラスがあります。One の内部クラスの 2 つ。クラス 2 のコンストラクターは、以下に示すようにクラス 1 の weak_ptr を受け取り、後で使用できるように格納します。

Class One  
{    
    Class Two    
    {  
    private:
      std::weak_ptr<One> m_wptrOne;

    public:
      Two(std::weak_ptr<One> wptrOne)
      {
          m_wptrOne = wptrOne;
          /* m_wptr is used later by class Two if not expired and valid ofcourse */
      }
  }; // End Class Two

  .....
  void foo()  
  {  
       std::shared_ptr sptrOne(this); 
       Two obj(sptrOne);  

    .... /* do my work */  
  } // Program crashes when foo terminates 
}; //End Class One

関数 foo が返されるとクラッシュします。これは、「sptr」が「this」ポインターを唯一の所有者であると考えて解放しようとしていると思われるためです。

どうすればこの問題を解決できますか? または、私のプログラムは構造的に間違っていますか? どんな提案でも大歓迎です。

ありがとう、
トゥシャール

4

2 に答える 2

2

ライブラリのユーザーが共有ポインタとしてヒープ上にオブジェクトを作成することを強制したくありません。

次に、内部クラスweak_ptr. a を使用するには、aを使用するweak_ptr 必要がshared_ptrあります。shared_ptrポインターがいつ破棄されたかを知るために、作成する機械に依存しています。したがって、ユーザーに を使用させたくない場合shared_ptrは、クラスが でラップされることを期待することはできませんshared_ptr。それからを作成するようweak_ptrに。

weak_ptrしたがって、ユーザーがこれらのオブジェクトをヒープ上に作成できないようにする場合は、内部クラスを独立させる必要があります。

shared_ptr特別な削除を使用するスタックオブジェクトをユーザーにラップさせるように強制する何かを試すことができます。しかし、それは単にヒープを割り当てるよりもはるかに面倒です。

于 2013-08-06T23:48:42.497 に答える
1

enable_shared_from_this以下は、から弱い所有権のセマンティクスを渡すために使用する例ですthis

自動保存期間を持つオブジェクトに対して弱い所有権のセマンティクスを表現することはできないことに注意してください。

あなたが言及したクラッシュは、おそらく、共有されていないオブジェクトから shared_ptr を取得しようとしたために発生したshared_from_thisタイプの例外です。std::bad_weak_ptr

#include <memory>

class One   : public std::enable_shared_from_this<One>
{    
public:
    class Two    
    {  
    private:
      std::weak_ptr<One> m_wptrOne;

    public:
      Two(std::weak_ptr<One> wptrOne)
      {
          m_wptrOne = wptrOne;
          /* m_wptr is used later by class Two if not expired and valid ofcourse */
      }
  }; // End Class Two

  //.....
  void foo()  
  {  
       std::shared_ptr<One> sptrOne = shared_from_this(); 
       Two obj(sptrOne);  

    //.... /* do my work */  
  } // Program crashes when foo terminates 
}; //End Class One


int main()
{
    auto one = std::make_shared<One>();
    one->foo();
}
于 2013-08-06T23:48:27.090 に答える