Visual C++ 2010 でshared_ptr
この度、Visual Studio 2010からC++0xのshared_ptrを使うことができるようになったということで試してみました。
#include <stdio.h> #include <memory> int main() { const int SIZE = 5; std::tr1::shared_ptr<int> p1(new int[SIZE], [](int* ptr) { delete [] ptr; });//配列型は、delete [] ptr; とメモリを解放する必要がある //std::tr1::shared_ptr<int> p1(new int[SIZE]);//int型の配列を確保 std::tr1::shared_ptr<int> p2; //p1が参照しているint型配列の値を設定する for (int i = 0; i < SIZE; i++) { p1.get()[i] = i; } //p1、p2が同じint型配列を参照する p2 = p1; //参照カウントを表示 printf("use_count: %d\n\n", p1.use_count()); //p1、p2が参照している配列の要素を変更する p1.get()[0] = 999; p2.get()[1] = 999; //p1, p2それぞれの配列の要素を表示する for (int i = 0; i < SIZE; i++) { printf("p1[%d] = %d\n", i, p1.get()[i]); } puts("\n"); for (int i = 0; i < SIZE; i++) { printf("p2[%d] = %d\n", i, p2.get()[i]); } return 0; }
p2 = p1 が実行された後で、参照カウンタが「2」になっている。p1、p2それぞれの参照先の要素の変更も反映されていることがわかる。
use_count: 2 <span class="deco" style="color:#FF0000;">p1[0] = 999 p1[1] = 999</span> p1[2] = 2 p1[3] = 3 p1[4] = 4 <span class="deco" style="color:#FF0000;">p2[0] = 999 p2[1] = 999</span> p2[2] = 2 p2[3] = 3 p2[4] = 4
次に、オブジェクトが破棄される(デストラクタが呼ばれる)タイミングを以下のコードで調べてみる。
#include <stdio.h> #include <memory> class MyClass { public: ~MyClass() { printf("Destructor called\n"); } }; int main() { std::tr1::shared_ptr<MyClass> p1; std::tr1::shared_ptr<MyClass> p2; printf("p1.use_count: %d\n", p1.use_count()); p1.reset(new MyClass()); printf("p1.use_count: %d\n", p1.use_count()); //p1とp2が同じMyClassオブジェクトを参照する p2 = p1; printf("p1.use_count: %d\n", p1.use_count()); p1 = NULL; printf("p1.use_count: %d\n", p1.use_count()); p2 = NULL;//ここで参照カウントがゼロになり、デストラクタが呼ばれる return 0; }
1つのMyClassオブジェクトを参照するshared_ptrが増える度に、参照カウンタが増加することが分かる。
そして、shared_ptrにNULLを代入すると参照カウンタが減少し、参照カウンタがゼロになるとMyClassオブジェクトのデストラクタが呼ばれる。
p1.use_count: 0 p1.use_count: 1 p1.use_count: 2 p1.use_count: 1 Destructor called
参考
http://msdn.microsoft.com/ja-jp/library/bb982026.aspx
http://blog.livedoor.jp/hkoie/archives/51164311.html