読者です 読者をやめる 読者になる 読者になる

std::weak_ptr について軽く調べてみた

C++

std::weak_ptr について軽く調べてみた。
C++ のスマートポインタまわりの知識は全然なかったりする。

[std::weak_ptr]

std::shared_ptr が参照カウントを使用してオブジェクトの所有権を管理するのに対して、std::weak_ptr は所有権を持たずにオブジェクトを参照するだけのスマートポインタになる。 例えば std::shared_ptr の場合は、

std::shared_ptr<X> shared1;
{
    std::shared_ptr<X> shared2{new X{}};
    shared1 = shared2;
    // shared1 が X を参照しているので
    // ここを抜けるタイミングではまだ X は開放されない
}

// shared1 が解放されるタイミングで X も解放される

というようにいずれかの std::shared_ptr が参照していれば、そのオブジェクトは解放されない。
一方、std::weak_ptr はオブジェクトを参照していても、そのオブジェクトが解放される可能性がある。

std::weak_ptr<X> weak;
// 参照先が存在するかどうかを expired() でチェックできる
std::cout << weak.expired() << std::endl;
{
    std::shared_ptr<X> shared{new X{}};
    weak = shared;
    std::cout << weak.expired() << std::endl;
    // まだ weak が X を参照しているが
    // ここを抜けるタイミングで X が開放される
}
// weak の参照先はすでに存在していないので false が返ってくる
std::cout << weak.expired() << std::endl;

こんな感じに std::weak_ptr から参照されていても std::shared_ptr はオブジェクトの解放を行う。
簡単に言えばオブジェクトの所有権を管理せず『オブジェクトを参照したいだけ』の場合に std::weak_ptr が利用できる。
例えば、親子関係でどちらか一方を参照したい時に std::weak_ptr が使えると思う。
std::weak_ptr はよくわかってなかったけど、結構利用できそうな場面がありそう。

[参照]

http://qiita.com/MasayaMizuhara/items/0b78f7046aaa6d17bb66