[C++] shared_ptrをインスタンス変数として保持できるのか

C++でshared_ptrがありますが、それをインスタンス変数に入れるとどうなるのでしょうか。

サンプルコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <iostream>
#include <memory>
 
class Hoge;
 
class Foo {
public:
    Foo(std::shared_ptr<Hoge> hoge) : hoge_(hoge){
    };
    ~Foo(){
        std::cout << "Destroy FOO" << std::endl;
    };
 
private:
    // shared_ptrでインスタンス変数を保持する
    std::shared_ptr<Hoge> hoge_;
 
};
 
 
class Hoge {
 
public:
    Hoge(const std::string& name) : name_(name){
    };
    ~Hoge(){
        std::cout << "Destroy [" + name_ + "]" << std::endl;
    };
 
private:
    std::string name_;
 
};
 
int main() {
 
    {
        std::shared_ptr<Hoge> hoge(new Hoge("shared_pointer"));
        std::shared_ptr<Foo> foo(new Foo(hoge));
    }
    std::cout << " ----- " << std::endl;
 
    return 0;
}

FooがHogeをshared_ptrで保持しているパターンです。

実行結果

Destroy FOO
Destroy [shared_pointer]
 -------

FOOがdeleteされてからHogeがdeleteされています。

Fooがshared_ptrでないパターン

もうひとパターン試してみます。
2つのfooでHogeを参照してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
 
    Foo *p_foo;
    {
        std::shared_ptr<Hoge> hoge(new Hoge("shared_pointer"));
        std::shared_ptr<Foo> foo(new Foo(hoge));
        p_foo = new Foo(hoge);
    }
    std::cout << " ----- " << std::endl;
 
    delete p_foo;
 
    return 0;
}

実行結果

Destroy FOO
 -----
Destroy FOO
Destroy [shared_pointer]

ちゃんと全ての参照が終わってから解放されています。

shared_ptrでインスタンス変数を管理すれば、解放し忘れなどなくて良さそうです。
循環参照すると解放されなくなるようなので注意が必要です。
何か良いサンプルコードを読んで勉強したいです。

ちなみに、MacのCarbonフレームワークでは、Retain, Releaseで参照カウンターを制御できたのでわかりやすくメモリ管理できました。

0 件のコメント :

コメントを投稿