質問

コードでboost:shared_ptrを広範囲に使用しています。実際、ヒープに割り当てられるオブジェクトのほとんどは、shared_ptrによって保持されます。残念ながら、これはthisを受け取る関数にbar(boost::shared_ptr<Foo>(this))を渡すことができないことを意味します。次のコードを検討してください:

void bar(boost::shared_ptr<Foo> pFoo)
{
    ...
}

void Foo::someFunction()
{
    bar(this);
}

ここには2つの問題があります。まず、<=>のT *コンストラクターが明示的であるため、これはコンパイルされません。 2番目に、<=>で強制的にビルドすると、オブジェクトへの2番目の共有ポインターが作成され、最終的には二重削除になります。

これは私の質問に私をもたらします:それらのオブジェクトのいずれかのメソッド内から存在することがわかっている既存の共有ポインターのコピーを取得するための標準パターンはありますか?ここで唯一のオプションは侵入参照カウントを使用していますか?

役に立ちましたか?

解決

enable_shared_from_this から派生して、 <!> quot; shared_from_this()<!> quot;を使用できます。 <!> quot; this <!> quot;の代わりに自分の自己オブジェクトへの共有ポインタを生成します。

リンクの例:

#include <boost/enable_shared_from_this.hpp>

class Y: public boost::enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_from_this();
    }
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

メンバー関数からスレッドを生成して、これの代わりにshared_from_this()にboost :: bindを生成するのは良い考えです。オブジェクトが解放されないようにします。

他のヒント

shared_ptrの代わりに、関数パラメーターに生のポインターを使用するだけです。スマートポインターの目的はオブジェクトの有効期間を制御することですが、オブジェクトの有効期間はC ++スコープ規則によってすでに保証されています。少なくとも関数の終了までは存在します。つまり、呼び出し元のコードは、関数が戻る前にオブジェクトを削除することはできません。したがって、<!> quot; dumb <!> quot;の安全性;関数内のオブジェクトを削除しようとしない限り、ポインターは保証されます。

shared_ptrを関数に渡す必要があるのは、オブジェクトの所有権を関数に渡したいとき、または関数にポインターのコピーを作成させたいときだけです。

boostにはこのユースケースの解決策があります。 enable_shared_from_this

本当にバー内でpFooの共有コピーを作成していますか?内部でクレイジーなことをしていない場合は、次のようにします。


void bar(Foo &foo)
{
    // ...
}

C ++ 11では、shared_ptrおよびenable_shared_from_thisは標準ライブラリに含まれています。後者は、名前が示すように、この場合に正確です。

http://en.cppreference.com/w/cpp/memory/shared_ptr

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

上のリンクの例に基づいた例:

struct Good: std::enable_shared_from_this<Good>{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};

使用:

std::shared_ptr<Good> gp1(new Good);
std::shared_ptr<Good> gp2 = gp1->getptr();
std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';

ポインターを受け入れる関数は、次の2つの動作のいずれかを実行しようとしています。

  • 渡されたオブジェクトを所有し、スコープ外になったら削除します。この場合、X *を受け入れて、すぐにscoped_ptrをそのオブジェクトの周りに(関数本体で)ラップできます。これは、<!> quot; this <!> quot;を受け入れるために機能します。または、一般的に、ヒープに割り当てられたオブジェクト。
  • 渡されるオブジェクトへの
  • ポインタの共有(所有しない)。この場合、scoped_ptrを使用したくない 関数の最後でオブジェクトを削除したくない。この場合、理論的に必要なのはshared_ptrです(他の場所でlinked_ptrと呼ばれるのを見てきました)。ブーストライブラリには、 shared_ptrのバージョンがあります。これは、Scott MeyersのEffective C ++ book(第3版の項目18)でも推奨されています。

編集:おっと、質問を少し読み間違えましたが、この回答が質問に正確に対応していないことがわかりました。これが同様のコードで作業している人に役立つかもしれない場合に備えて、とにかくそのままにしておきます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top