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が利用可能だ。