5
typedef boost::shared_ptr<SomeData> data_ptr;
data_ptr cached_ptr;   // class member 
bool someWork(data_ptr& passed_ptr)
{
  // must copy passed_ptr = cached_ptr under some conditions
  // without pointing at the same memory 
  // I saw somewhere that I should do 
  // passed_ptr.reset(new SomeData(???))
  // I don't have a "reset" on passed_ptr
}

ドキュメントを見ました。

コンストラクターのコピーと変換

shared_ptr(shared_ptr const & r); // never throws
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
Requires: Y* should be convertible to T*.

Effects: If r is empty, constructs an empty shared_ptr; otherwise,
         constructs a shared_ptr that shares ownership with r.

それがどのように機能するのかわかりません-このようなものですか?

passed_ptr = shared_ptr(cached_ptr);

? const はどこに行きますか?そして、彼らが所有権を共有するとはどういう意味ですか? 「passed_ptr」を変更すると、その変更は「cached_ptr」に影響しますか?

例が見つかりません...助けてください。

ありがとうございました。

4

3 に答える 3

12

があり、shared_ptrそれを別の に割り当てるとshared_ptr、これら 2 つの共有ポインタはオブジェクトの所有権を共有します。つまり、指定されたオブジェクトの所有権の参照カウントが 1 増加します。

実際、上記の行では、一時共有ポインターを作成する必要はまったくありません。これで十分です:

passed_ptr = cached_ptr;

とにかく、 a のコピー構築はshared_ptr基本的に同じロジックに従います: 共有ポインターで開始し、同じオブジェクトを共同所有する 2 つの共有ポインターで終了します (つまり、これらの共有ポインターの両方が取得された場合にのみオブジェクトが破棄されます)。破壊されました)。したがって、これを行うと:

passed_ptr = shared_ptr(cached_ptr);

cached_ptr実際には、特定のオブジェクトへの1 つの共有ポインターpassed_ptr(参照カウントを 2 に戻します)。

一方、によって指されているオブジェクトのコピーpassed_ptrへの共有ポインターとして保持することが必要な場合は、むしろそうする必要があります (もちろん、コピー可能であると仮定します)。cached_ptrData

passed_ptr = boost::make_shared<Data>(*cached_ptr);

または、代わりに:

passed_ptr.reset(new Data(*cached_ptr));
于 2013-05-07T16:16:30.523 に答える
9

わかった。これについて話せるか見てみましょう。

std::shared_ptr<Data> x = std::make_shared<Data>();
std::shared_ptr<Data> y = x;

assert(x.get() == y.get());

x何を指すかについて何かを変更すると、情報も変更yされます。同じものを指しているからです。

x->member = 3;
assert(x->member == 3);
assert(y->member == 3);

xを指すかを変更せずに、何をy指すかを変更できます。

x = std::make_shared<Data>();
assert(x.get() != y.get());

これを行うと、 への変更が にx反映されませんy。それらは異なるものを指しているからです。

x->member = 4;
assert(x->member == 4);
assert(y->member != 4);

のコンテンツのコピーを作成xして に保存するy場合は、新しい共有オブジェクトを作成する必要があります。

y = std::make_shared<Data>(*x);

この時点で、 と の両方xyそのメンバー変数が 4xに設定されてい*yます*x

assert(x->member == 4);
assert(y->member == 4);

しかし、xyはメモリ内の異なるものを指しているため、そのうちの 1 つを変更できます。

assert(x.get() != y.get();
x->member = 3;
assert(x->member == 3);
assert(y->member == 4);

関数に shared_ptr を渡す場合は、最初のケースと同じです。

void func(std::shared_ptr<Data> z) {
    assert(x.get() == z.get());
}

func(x);

を使用して、特定の shared_ptr の内容を解放することもできreset()ます。これにより、shared_ptr が指している値が NULL になります。

x.reset();
assert(x.get() == NULL);

const の正確性に関しては、少し奇妙です。

const std::shared_ptr<Data> x;
x.reset(); // Fails because the shared_ptr is const.
x->member = 3; // Succeeds because Data is not const.

std::shared_ptr<const Data> x;
x.reset(); // Succeeds because the shared_ptr is not const.
x->member = 3; // Fails because Data is const.
于 2013-05-07T16:15:54.460 に答える