C++のスマートポインタといえばstd::unique_ptr

昔はauto_ptr使ったりしたけど、もう古いそうです。問題あったらしい。

ネタ元


以下消えると困るのでコピペ


まずは基本的な使い方です。

コンストラクタに管理して欲しいリソースを渡すだけで使えます。

std::unique_ptr<リソース型> 変数名(リソースの生ポインタ);

後はスマートポインタの寿命と同時に自動的にリソースが開放されます。
配列かそうで無いかも自動で判断してdeleteとdeleteを呼び分けてくれます。*, ->, などの演算子もオーバーロードされているので主な使い方は生ポインタと同じです。
APIに渡す生ポインタが必要な時にはget()、明示的に開放したい場合はreset()なども可能です。

#include <memory>

class Hoge
{
public:
    void Func()
    {
    }
};

void funcRawPtr(int* raw)
{
}

// テスト00 : 基本的な使い方
void test00()
{
    // 組み込み型
    {
        // 初期値0でintを確保
        std::unique_ptr<int> a(new int(0));
        
        // 生ポインタと同じように扱える
        *a = 10;
        
    }   // delete不要、スコープを抜けると自動的に開放される
    
    // クラス
    {
        // Hogeを確保
        std::unique_ptr<Hoge> hoge(new Hoge());
        
        // 生ポインタと同じように扱える
        hoge->Func();
        
    }   // delete不要、スコープを抜けると自動的に開放される
    
    // 配列
    {
        // int3個分を確保
        std::unique_ptr<int[]> a(new int[3]);
        
        // 生ポインタと同じように扱える
        a[0] = 0;
        a[1] = 10;
        a[2] = 20;
        
    }   // delete[]不要、スコープを抜けると自動的に開放される
    
    // 生ポインタとの互換
    {
        std::unique_ptr<int> a(new int(10));
        std::unique_ptr<int> b;        // 何も指定しない場合中身はnullptrに
        
        // 関数の引数に生ポインタを要求される場合はget()で生ポインタを参照できる
        funcRawPtr(a.get());
        
        // ポインタが有効かどうか判定できる
        if (a)
        {
            // ○ aは有効
        }
        if (b)
        {
            // × bは無効
        }
    }
    
    // 明示的な開放:その1
    {
        std::unique_ptr<int> a(new int(10));
        
        // reset()で明示的に開放することもできる
        a.reset();
        
        if (a)
        {
            // × aは解放済み
        }
    }

    // 明示的な開放:その2
    {
        std::unique_ptr<int> a(new int(10));
        
        // reset()に新しいリソースを渡すと古いリソースを開放した後に新しいリソースへ更新できる
        a.reset(new int(20));    // 最初の10の分はここで同時に開放される
        
        if (a)
        {
            // ○ aの参照先の値は20
        }
        
    }   // 20の分はスコープを抜けると自動的に開放
}