これからC++11を学ぶ君に。生ポとおさらば unique_ptr編

#はじめに
C++はメモリ管理が難しい、ガーベージコレクタがないからリークする
だからC++を使いたくない
という話をよく聞くので

基本的に 生ポインター（生ポ）を使わず、賢いポインタ（smart pointer）を使いましょう

私はC++の扱いに慣れている！ という人でも、例外時に解放忘れたりと
ありがちなので、慣れた人でも smart pointerを使う事がよろしいかと思います

```cpp:exeption.cpp
void hoge(){
  char *p = new char[100];

  // ここで例外発生したら pはリークしますよ！

  delete p;
}
```

よくある、みつけにくいメモリリークですよね。
ちゃんと try/catch でかこみ finalizeで解放し、例外をthrowし直さないとダメですね
面倒だし、無駄な例外処理が必要になり速度的にも あれですよね。


##まずは auto_ptr
STLにはauto_ptrというものがあり、スマートポインタとして使われてましたが
auto_ptrは deprecated (非推奨、削除予定)なので、 unique_ptr を使いましょう
unique_ptrは、昔 boost::scoped_ptrって呼ばれてたやつですね。

ってことで、auto_ptr がダメな理由

```cpp:auto_ptr.cpp

#include <iostream>
#include <string>
#include <memory>



using namespace std;


class test{
public:
	string s;

	test( const char* c ){ 
		s = c; 
		cout << "new:" << val() << endl; 
	}
	
	virtual ~test(){ 
		cout << "delete:" << val() << endl; 
	}

	const char* val(){
		return( s.c_str() ); 
	}
};

template<class T>
void print(const T& c) {
  c.get() ? cout<<c->val() : cout << "(null)";
  cout << endl;
}

void exec()
{
	auto_ptr<test> p1(new test( "p1" ));
	auto_ptr<test> p2(new test( "p2" ));
	p1 = p2;
	
	print<auto_ptr<test> >(p1);
	print<auto_ptr<test> >(p2);

}

int main()
{
	cout << "start" << endl;
	exec();

	getch();


    return 0;
}
```

出力結果

```
start
new:p1
new:p2
delete:p1
p2
(null)
delete:p2
```

ちゃんと解放はされますが
p1 = p2;
の部分で p1が保持していた値は deleteされ p2のポインタに上書きされ、p2のポインタは null_ptr になります

つまりこれは 所有権の移動、ムーブの動作ですが　= なのでコピーと間違えやすい。


##unique_ptr：コピー
上記のソースを unique_ptrにかえると
p1 = p2; 
の部分でコンパイルエラーが発生します！！

例えばVisualStudioでは

```cpp:unique_ptr
	_Myt& operator=(_Myt&& _Right) _NOEXCEPT
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, do the move
			reset(_Right.release());
			this->get_deleter() = _STD forward<_Dx>(_Right.get_deleter());
			}
		return (*this);
		}


	unique_ptr(const _Myt&);	// not defined
	_Myt& operator=(const _Myt&);	// not defined
```

右辺参照は実装され
コピーコンストラクタ、代入演算子が禁止されています

auto_ptrと同じく ムーブをしたければ std::move を明示的に使いましょう！ 


##unique_ptr: 配列
auto_ptrでは ポインタ配列をちゃんと解放出来なかった (deleteが呼ばれる・・)けど
unique_ptrでは 
unique_ptr<test[]> p(new test[10]);
等と書くと、デリート時にちゃんと delete[]が呼ばれます

```cpp:配列
template<class _Ty,
	class _Dx>
	class unique_ptr<_Ty[], _Dx>
		: private _Unique_ptr_base<_Ty, _Dx,
			is_empty<_Dx>::value
				|| is_same<default_delete<_Ty[]>, _Dx>::value>
	{	// non-copyable pointer to an array object
```


##unique_ptr: カスタムデリータ
delete時の挙動を変更する事ができます
これの何が便利かというと、delete以外で終了処理をする場合
例えば FILE は fclose、mallocはfree で解放しますが
コンストラクタの第二引数に deleteオブジェクトを登録する事で
スマートに fclose、free が出来ます

```cpp:custom_deleta
	unique_ptr<FILE,decltype(&fclose)> p1( fopen("p1","w"), fclose );
	unique_ptr<void,decltype(&free)> p2( malloc(100), free  );
	
	unique_ptr<FILE,decltype(&fclose)> p3( fopen("p1","w"), ( [](FILE *fp){ cout << "fclose" << endl; return(fclose(fp));} ) );
	unique_ptr<void,decltype(&free)> p4( malloc(100), [](void*p){ cout << "free" << endl; free(p);} );
```

上２つが実際に使った例ですが、コンストラクト時に fopen、mallocをし、デストラクト時に fclose、free が出来ます
dectypeが凄く便利ですね！

下２つはそれを ラムダにし、複数の命令を書けるようにしました。

もちろん、スレッドハンドル、リソース 等なんでもつかえるので便利です

是非この機会に、リソースID等のプリミティブなものも 生で使わず スマートに使う事を心がけましょう

（リソースを生で使うのは アンチデザパタです！！）


##まとめ

生ポに頼るのはもうやめよう。
auto_ptrは deprecated なので使わない
unique_ptr を使おう！！
配列も正しく処理してくれるよ！！
カスタムデリータで、リソースもスマートに管理しよう！！

ただし、名前の通り unique です。所有権はただ１人。
ポインタを共有する事は出来ないので
複数から参照される場合は

shared_ptr、weak_ptr 使いましょう！