std::shared ptr
提供: C++入門
2014年1月3日 (金) 00:57時点におけるDaemon (トーク | 投稿記録)による版 (ページの作成:「std::shared_ptr とは、C++11で追加された参照カウンタを持ち、リソースが共有できるスマートポインタです。 '''読み方'...」)
スポンサーリンク
std::shared_ptr とは、C++11で追加された参照カウンタを持ち、リソースが共有できるスマートポインタです。
読み方
- std::shared_ptr
- えすてぃーでぃー しぇあーど ぴーてぃーあーる
目次
概要
参照カウンタで所有者の数をカウントします。共有が増えるたびに、カウンタが1増やされ、共有が減るたびに-1されます。カウンタが0になった時点で、リソースは解放されます。 参照カウントを持つため、メモリの使用量や管理コストが上がるため、性能面では、生のポインタと比較すれば、劣ります。
基本的な使い方は、以下の通りです。
std::shared_ptr<T> name(リソースの生のポインタ);
メモリの確保の場合には、以下を通りです。
std::shared_ptr<T> name = std::make_shared<T>(コンストラクタの引数);
#include <iostream> #include <memory> using namespace std; int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); cout << a << endl; cout << *a << endl; *a = 456; cout << *a << endl; return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr1.cpp -o std_shared_ptr1
実行例
% ./std_shared_ptr1 0x2840403c 123 456
#include <iostream> #include <memory> using namespace std; class C { private: std::string name_; int age_; public: C(std::string name, int age):name_(name), age_(age) {} virtual ~C() { cout<<__PRETTY_FUNCTION__<<endl; } void doit() { cout<<__PRETTY_FUNCTION__<<endl; } }; int main(int argc, char const* argv[]) { { auto a = std::make_shared<C>("Foo", 123); a->doit(); } // destroy C return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr2.cpp -o std_shared_ptr2
実行例
% ./std_shared_ptr2 void C::doit() virtual C::~C()
関数にポインタを渡す例 get()
#include <iostream> #include <memory> using namespace std; void f(int *p) { } int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); f(a.get()); // ポインタを関数に渡す例 return 0; }
明示的な解放の例 reset()
#include <iostream> #include <memory> using namespace std; int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); a.reset();// 明示的な解放 cout << (a ? "Not reset" : "reset") << endl; // reset と表示される return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr4.cpp -o std_shared_ptr4
実行例
% ./std_shared_ptr4 reset
解放しつつ新しいアドレスと値をセットする例
#include <iostream> #include <memory> using namespace std; int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); cout << a << endl; a.reset(new int(99));// 明示的な解放と再設定 cout << (a ? "set" : "reset") << endl; // set と表示される cout << a << endl; // 最初とは違うアドレスが表示される cout << *a << endl; // 99 が表示される return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr5.cpp -o std_shared_ptr5
実行例
% ./std_shared_ptr5 0x2840403c set 0x28465088 99
参照カウントとオーナーの確認の例
#include <iostream> #include <memory> using namespace std; int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); cout << a.use_count() << endl; // 参照カウントは 1 { auto b = a; // b と共有する cout << "count is " << a.use_count() << endl; // 所有者がaとbなので、a は、uniqueな所有者ではないので、 // not unique と表示される。 cout << (a.unique() ? "a is unique" : "a is not unique") << endl; } // b が解放され、参照カウントが1減る cout << "count is " << a.use_count() << endl; // 所有者は、a しか存在しないので、 unique と表示される。 cout << (a.unique() ? "a is unique" : "a is not unique") << endl; return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr6.cpp -o std_shared_ptr6
実行例
% ./std_shared_ptr6 1 count is 2 a is not unique count is 1 a is unique
std::swapでリソースを交換する例
std::swapでリソースを交換します。
#include <iostream> #include <memory> using namespace std; int main(int argc, char const* argv[]) { auto a = std::make_shared<int>(123); auto b = std::make_shared<int>(456); cout << "a is " << a << " " << *a << endl; cout << "b is " << b << " " << *b << endl; cout << "swap" << endl; std::swap(a,b); cout << "a is " << a << " " << *a << endl; cout << "b is " << b << " " << *b << endl; return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_shared_ptr7.cpp -o std_shared_ptr7
実行例
% ./std_shared_ptr7 a is 0x2840403c 123 b is 0x2840404c 456 swap a is 0x2840404c 456 b is 0x2840403c 123
関連項目
- ポインタ / NULL / nullptr
- スマートポインタ
- std::unique_ptr
- std::shared_ptr
- std::weak_ptr
- std::auto_ptr (非推奨)
- boost::shared_ptr
- boost::scoped_ptr
- boost::weak_ptr
- boost::intrusive_ptr
ツイート
スポンサーリンク