C++11標準ライブラリとBoost.Smart_Pointersライブラリでそれぞれ提供される共有ポインタshared_ptr
クラステンプレートの相互運用に関するメモ。本記事の内容はStack Overflowで見つけた質問と回答内容に基づく。
注意:あくまで “技術的に相互運用が可能であること” を示すだけで、実行時効率や保守性の観点からは片方で統一するのが望ましい。
#include <memory> #include <boost/shared_ptr.hpp> // boost::shared_ptr → std::shared_ptr template<typename T> boost::shared_ptr<T> make_shared_ptr(const std::shared_ptr<T>& ptr) { return boost::shared_ptr<T>(ptr.get(), [ptr](T*){}); } // std::shared_ptr → boost::shared_ptr template<typename T> std::shared_ptr<T> make_shared_ptr(const boost::shared_ptr<T>& ptr) { return std::shared_ptr<T>(ptr.get(), [ptr](T*){}); }
変換先shared_ptr
オブジェクトのコンストラクタに「元shared_ptr
オブジェクトが指す生ポインタ値」と「元shared_ptr
オブジェクトのコピーを保持し、自shared_ptr
での所有権放棄時には何もしないカスタムデリータ」を指定している。
自shared_ptr
が所有権を保持している間は、そのカスタムデリータ(=ラムダ式によるクロージャオブジェクト)によって元shared_ptr
の所有権を維持する。自shared_ptr
が所有権を放棄するタイミングで、カスタムデリータオブジェクトの解放=元shared_ptr
の参照カウントが減らされる。
// 波括弧{}は該当行実行後の所有カウントを表す std::shared_ptr<int> sp0 = std::make_shared<int>(42); // std{1} std::shared_ptr<int> sp1 = sp0; // std{2} boost::shared_ptr<int> bp0 = make_shared_ptr(sp1); // boost{1},std{3} sp0.reset(); sp1.reset(); // boost{1},std{1} bp0.reset(); // boost{0},std{0}