C++11講座5回
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
第5回はスマートポインタになります。
C++ではメモリ確保を行う場合、自動で解放しないので解放処理...
1: #include <iostream>
2:
3: using namespace std;
4:
5: class Hoge
6: {
7: public:
8: Hoge()
9: {
10: cout << "Constructor" << endl;
11: }
12: ~Hoge()
13: {
14: cout << "Destructor" << endl;
15: }
16:
17: int num;
18: };
19:
20: int main()
21: {
22: //メモリ確保
23: Hoge* p1 = new Hoge();
24: Hoge* p2 = new Hoge[5];
25:
26: //初期化
27: p1->num = 10;
28: for (int i = 0; i < 5; i++)
29: {
30: (p2+i)->num = i;
31: }
32:
33: //表示
34: cout << p1->num << endl;
35: for (int i = 0; i < 5; i++)
36: {
37: cout << (p2+i)->num << endl;
38: }
39:
40: //メモリ解放
41: delete p1;
42: delete [] p2;
43
44: return 0;
45: }
40行目から先のdeleteを書かないと、確保したメモリが終了し...
上記のプログラム程度ならdeleteを書き忘れることはないと思...
newとdeleteが各所に散らばるため確認が難しくなります。
C++11では自動で解放処理をしてくれるスマートポインタが登場...
新しく<memory>をインクルードすることにより
・unique_ptr
・shared_ptr
・weak_ptr
の3つのスマートポインタが使えるようになります。
最初のプログラムのメモリ確保部分を書き直すと
1: int main()
2: {
3: //メモリ確保
4: unique_ptr<Hoge> p1(new Hoge);
5: unique_ptr<Hoge[]> p2(new Hoge[5]);
6:
7: //初期化
8: p1->num = 10;
9: for (int i = 0; i < 5; i++)
10: {
11: p2[i].num = i;
12: }
13:
14: //表示
15: cout << p1->num << endl;
16: for (int i = 0; i < 5; i++)
17: {
18: cout << p2[i].num << endl;
19: }
20:
22: return 0;
23: }
deleteを書いていませんが、実行するとデストラクタが呼ばれ...
unique_ptrはスコープを抜けた時点でポインタを自動でdelete...
次にshaerd_ptrの例を見ます。
1: int main()
2: {
3: //メモリ確保
4: shared_ptr<Hoge> p1 = make_shared<Hoge>();
5:
6: cout << p1.use_count() << endl;//1
7:
8: {
9: //p2に代入
10: shared_ptr<Hoge> p2 = p1;
11:
12: cout << p1.use_count() << endl;//2
13:
14: p2->num = 10;
15: }//p2はここで解放される(Hogeは破棄されない)
16:
17: cout << p1.use_count() << endl;//1
18:
19: cout << p1->num << endl;//p2で代入した10が表示される
20:
21: return 0;
22: }
shaerd_ptrは参照カウント方式で、オブジェクトを参照するsha...
先ほどのunique_ptrは複数のunique_ptrで1つのオブジェクト...
shaerd_ptrは複数のshaer_ptrで1つのオブジェクトを参照する...
次にweak_ptrを使う例について説明します。
先ほどのshaerd_ptrは循環参照になった場合に解放されない問...
※実行しないでください
1: #include <iostream>
2: #include <memory>
3:
4: using namespace std;
5:
6: class Hoge
7: {
8: public:
9: Hoge()
10: {
11: cout << "Constructor" << endl;
12: }
13: ~Hoge()
14: {
15: cout << "Destructor" << endl;
16: }
17:
18: shared_ptr<Hoge> ptr;
19: };
20:
21: int main()
22: {
23: //メモリ確保
24: shared_ptr<Hoge> p1(new Hoge);
25: shared_ptr<Hoge> p2(new Hoge);
26:
27: p1->ptr = p2;
28: p2->ptr = p1;
29:
30 return 0;
31: }
このプログラムだと循環参照が発生しているため、メモリの解...
本当にメモリリークしているかの確認はメモリリーク検出を参...
この解決方法として弱い参照であるweak_ptrがあります。
weak_ptrはshaerd_ptrが持っているオブジェクトを参照するポ...
1: class Hoge
2: {
3: public:
4: Hoge()
5: {
6: cout << "Constructor" << endl;
7: }
8: ~Hoge()
9: {
10: cout << "Destructor" << endl;
11: }
12:
13: weak_ptr<Hoge> ptr;//weak_ptrに変える
14: };
これによってスコープを抜けた時点でカウンタが残っていてもd...
また、weak_ptrは参照先が生存しているかを確認する機能があ...
1: int main()
2: {
3: //メモリ確保
4: shared_ptr<Hoge> shar_p = make_shared<Hoge>();
5: weak_ptr<Hoge> weak_p;
6:
7: weak_p = shar_p;
8:
9: //weak_ptrからは直接操作出来ないので、lock()を使うこ...
10: if (auto p = weak_p.lock())
11: {
12: p->num = 10;
13: }
14:
15: cout << shar_p->num << endl;//10が表示される
16:
17: shar_p.reset();//解放
18:
19: //解放されているかの確認はexpired()で出来る
20: if (weak_p.expired())
21: {
22: cout << "expired" << endl;
23: }
24:
25: return 0;
26: }
スマートポインタを利用することによって、メモリ解放に関す...
unique_ptrはスコープを抜けた時点でdeleteするという単純な...
shaerd_ptr、weak_ptrは少し癖がありますが、どちらも強力な...
以上でスマートポインタの説明を終了します。
前→C++11講座4回
次→C++11講座6回
#vote(そのためのポインタ[2],C++こわれる[1],エイシャア[1])
終了行:
第5回はスマートポインタになります。
C++ではメモリ確保を行う場合、自動で解放しないので解放処理...
1: #include <iostream>
2:
3: using namespace std;
4:
5: class Hoge
6: {
7: public:
8: Hoge()
9: {
10: cout << "Constructor" << endl;
11: }
12: ~Hoge()
13: {
14: cout << "Destructor" << endl;
15: }
16:
17: int num;
18: };
19:
20: int main()
21: {
22: //メモリ確保
23: Hoge* p1 = new Hoge();
24: Hoge* p2 = new Hoge[5];
25:
26: //初期化
27: p1->num = 10;
28: for (int i = 0; i < 5; i++)
29: {
30: (p2+i)->num = i;
31: }
32:
33: //表示
34: cout << p1->num << endl;
35: for (int i = 0; i < 5; i++)
36: {
37: cout << (p2+i)->num << endl;
38: }
39:
40: //メモリ解放
41: delete p1;
42: delete [] p2;
43
44: return 0;
45: }
40行目から先のdeleteを書かないと、確保したメモリが終了し...
上記のプログラム程度ならdeleteを書き忘れることはないと思...
newとdeleteが各所に散らばるため確認が難しくなります。
C++11では自動で解放処理をしてくれるスマートポインタが登場...
新しく<memory>をインクルードすることにより
・unique_ptr
・shared_ptr
・weak_ptr
の3つのスマートポインタが使えるようになります。
最初のプログラムのメモリ確保部分を書き直すと
1: int main()
2: {
3: //メモリ確保
4: unique_ptr<Hoge> p1(new Hoge);
5: unique_ptr<Hoge[]> p2(new Hoge[5]);
6:
7: //初期化
8: p1->num = 10;
9: for (int i = 0; i < 5; i++)
10: {
11: p2[i].num = i;
12: }
13:
14: //表示
15: cout << p1->num << endl;
16: for (int i = 0; i < 5; i++)
17: {
18: cout << p2[i].num << endl;
19: }
20:
22: return 0;
23: }
deleteを書いていませんが、実行するとデストラクタが呼ばれ...
unique_ptrはスコープを抜けた時点でポインタを自動でdelete...
次にshaerd_ptrの例を見ます。
1: int main()
2: {
3: //メモリ確保
4: shared_ptr<Hoge> p1 = make_shared<Hoge>();
5:
6: cout << p1.use_count() << endl;//1
7:
8: {
9: //p2に代入
10: shared_ptr<Hoge> p2 = p1;
11:
12: cout << p1.use_count() << endl;//2
13:
14: p2->num = 10;
15: }//p2はここで解放される(Hogeは破棄されない)
16:
17: cout << p1.use_count() << endl;//1
18:
19: cout << p1->num << endl;//p2で代入した10が表示される
20:
21: return 0;
22: }
shaerd_ptrは参照カウント方式で、オブジェクトを参照するsha...
先ほどのunique_ptrは複数のunique_ptrで1つのオブジェクト...
shaerd_ptrは複数のshaer_ptrで1つのオブジェクトを参照する...
次にweak_ptrを使う例について説明します。
先ほどのshaerd_ptrは循環参照になった場合に解放されない問...
※実行しないでください
1: #include <iostream>
2: #include <memory>
3:
4: using namespace std;
5:
6: class Hoge
7: {
8: public:
9: Hoge()
10: {
11: cout << "Constructor" << endl;
12: }
13: ~Hoge()
14: {
15: cout << "Destructor" << endl;
16: }
17:
18: shared_ptr<Hoge> ptr;
19: };
20:
21: int main()
22: {
23: //メモリ確保
24: shared_ptr<Hoge> p1(new Hoge);
25: shared_ptr<Hoge> p2(new Hoge);
26:
27: p1->ptr = p2;
28: p2->ptr = p1;
29:
30 return 0;
31: }
このプログラムだと循環参照が発生しているため、メモリの解...
本当にメモリリークしているかの確認はメモリリーク検出を参...
この解決方法として弱い参照であるweak_ptrがあります。
weak_ptrはshaerd_ptrが持っているオブジェクトを参照するポ...
1: class Hoge
2: {
3: public:
4: Hoge()
5: {
6: cout << "Constructor" << endl;
7: }
8: ~Hoge()
9: {
10: cout << "Destructor" << endl;
11: }
12:
13: weak_ptr<Hoge> ptr;//weak_ptrに変える
14: };
これによってスコープを抜けた時点でカウンタが残っていてもd...
また、weak_ptrは参照先が生存しているかを確認する機能があ...
1: int main()
2: {
3: //メモリ確保
4: shared_ptr<Hoge> shar_p = make_shared<Hoge>();
5: weak_ptr<Hoge> weak_p;
6:
7: weak_p = shar_p;
8:
9: //weak_ptrからは直接操作出来ないので、lock()を使うこ...
10: if (auto p = weak_p.lock())
11: {
12: p->num = 10;
13: }
14:
15: cout << shar_p->num << endl;//10が表示される
16:
17: shar_p.reset();//解放
18:
19: //解放されているかの確認はexpired()で出来る
20: if (weak_p.expired())
21: {
22: cout << "expired" << endl;
23: }
24:
25: return 0;
26: }
スマートポインタを利用することによって、メモリ解放に関す...
unique_ptrはスコープを抜けた時点でdeleteするという単純な...
shaerd_ptr、weak_ptrは少し癖がありますが、どちらも強力な...
以上でスマートポインタの説明を終了します。
前→C++11講座4回
次→C++11講座6回
#vote(そのためのポインタ[2],C++こわれる[1],エイシャア[1])
ページ名: