Chapter 05: Smart Pointers and Memory Management¶
Chapter 05 Smart Pointers and Memory Management についてのノート。
5.1 RAII and Reference Counting¶
参照カウンターの概念をおさらいしておくこと。
RAII の格言を忘れぬこと。
従来の C++ ではリソースを解放するために new
と delete
を使うことを忘れないようにする必要があった。C++11 で参照カウンターを利用したスマートポインターの概念が導入され、プログラマーが手動で解放することを気にする必要がなくなった。ヘッダーファイル <memory>
をインクルードしてスマートポインター各種を用いる。
参照カウンターはガベージコレクションの手法よりも、不用オブジェクトを早く回収することができ、再利用処理中に長い待ち時間が発生することはない。資源の寿命をより明確に示す。
5.3 std::unique_ptr
¶
スマートポインター std::unique_ptr
は排他的で、同じ生ポインターを共有するような他のスマートポインターの存在しないことを保証する。つまりコピーすることができない。しかし、std::move
を使って、他の unique_ptr
に移すことなどは可能であることに注意。
std::make_shared
の std::unique_ptr
版は C++11 では存在しない。
5.4 std::weak_ptr
¶
std::shared_ptr
は次のような使い方をすると解放漏れが生じる。デストラクターを実装して、デバッガーでステップ実行すればわかる:
class A;
class B;
class A {
public:
std::shared_ptr<B> pointer;
};
class B {
public:
std::shared_ptr<A> pointer;
};
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->pointer = b;
b->pointer = a;
ここで std::weak_ptr
を採用する。これは参照カウンターを増やさない。
A::pointer
または B::pointer
の少なくとも一方の shared_ptr
を
weak_ptr
にすれば A
と B
双方のデストラクターが作動する。
std::weak_ptr
には operator*
や operator->
が実装されていないため、生の資源を操作することはできない。
std::weak_ptr
は std::shared_ptr
が存在するかどうかをチェックすることができる。
std::weak_ptr::expired()
は資源が解放されていない場合に限り false
を返す。
また、元のオブジェクトを指す std::shared_ptr
を取得する目的で使用することもできる。
std::weak_ptr::lock()
は、資源が解放されていない場合に限り、元の
std::shared_ptr
を返す。
読者ノート
本文は lock
しか言及していないが、owner_before
というメソッドもある。これらを使って本文の例を書き換えたものを考えたい。
Conclusion¶
多くの言語で一般的な技術であるスマートポインターだが、C++ ではこの技術が最近導入された。
Further Readings¶
- c++ - Why does C++11 have make_shared but not make_unique - Stack Overflow
C++14 から
std::make_unique
が利用可能だ。