1

同じアドレスに関連して、複数の shared_ptr カウンターがありますが、C++ 標準で禁止されていますか? 同じオブジェクトを指しているが、基になる参照カウント構造を共有していない複数の shared_ptr オブジェクトに関するその他の無数の質問。

上記の質問でオブジェクトが「enable_shared_from_this」を継承するとどうなりますか? 私の shared_from_this() は何を返しますか? カスタムの削除機能があるものか、ないものか?

struct B : boost::enable_shared_from_this<B> {
  boost::weak_ptr < B > get_weak() {
    return shared_from_this();
  }
};

void doNothing(B *) {
}

int main() {
  B * b0 = new B;

  boost::shared_ptr < B > sddb0(b0, doNothing);
  boost::weak_ptr < B > swddb0(sddb0->get_weak());
  //  Does this have a custom deleter???
  boost::shared_ptr < B > sddb1 = swddb0.lock();

  boost::shared_ptr < B > scdb0(b0);
  boost::weak_ptr < B > swcdb0(sddb0->get_weak());
  //  Does this *not* have a custom deleter???
  boost::shared_ptr < B > scdb1 = swcdb0.lock();
}
4

1 に答える 1

1

デリータは所有されたオブジェクトに関連付けられており、最後の所有者がその参照を削除したときにそれを破棄するために使用されるため、同じオブジェクトの所有権を共有するすべてのポインタもデリータを共有します。デリーターは個々のshared_ptrオブジェクトに保存されるのではなく、参照カウントと共にヒープに保存されるため、同じカウントを共有するすべてのオブジェクトによって共有されます。

それでは、コードを見てみましょう。まず、示されているようにコンパイルさえしなかったため、コードを修正する必要がありました。質問のコードをテストして、タイプミスを修正したり、欠落しているヘッダーを追加したりすることで人々の時間を無駄にしないようにすることをお勧めします。

これを書かないでください:

B * b0 = new B;

boost::shared_ptr < B > sddb0(b0, doNothing);

それを行う正しい方法は次のとおりです。

boost::shared_ptr < B > sddb0(new B, doNothing);

enable_shared_from_this<B>ベースには、コンストラクターweak_ptr<B>によって割り当てられるメンバーがあるため、によって返される共有ポインターと同様に、 と所有権を共有します。shared_ptrweak_ptrsddb0shared_from_this()

したがって、この質問に対する答えはイエスです。

//  Does this have a custom deleter???
boost::shared_ptr < B > sddb1 = swddb0.lock();

sddb1と所有権を共有してsddb0いるため、削除者も同じです。

を使用するか、 inにget_deleter書き込むか、 を使用してポインターの所有者を比較することで、それをテストできます。stdoutdoNothingowner_less

これにより、既存の共有ポインターと所有権を共有しないオブジェクトが作成されます。

boost::shared_ptr < B > scdb0(b0);

enable_shared_from_this<B>ベースのメンバーは上記weak_ptr<B>の行によって に再割り当てされるため、scdb0ではなく と所有権を共有しsddb0ます。したがって、get_weakその時点以降に呼び出すと、所有権を共有する弱いポインターが返されるscdb0ため、カスタムのデリータはありません。doNothing繰り返しますが、が呼び出されていないことを確認するか、 を使用することで簡単に確認できますowner_less

于 2012-07-28T23:16:46.020 に答える