shared_ptrの実装1

boostといえばスマートポインタ。
C言語からC++に移るときに最も感動したものがスマートポインタだったと思います。
スコープから抜けるときに誰からも参照されなくなったオブジェクトを自動的にdeleteしてくれるポインタクラスですね。

class Hoge{ ... };
int main()
{
    shared_ptr< int > a( new int( 1 ) );
    shared_ptr< Hoge > b( new Hoge() );

    cout << *a << endl;
    b->...();     //適当なメソッド

    return 0;
}//←ここでdeleteされる

このように使えるスマートポインタsmart_ptrを実装してみましょう。
とりあえず、最低限必要な機能だけを。

template < typename T >
class smart_ptr
{
private:
	T* ptr;
public:
	smart_ptr()
		: ptr( 0 )
	{}
	smart_ptr( T* ptr )
		: ptr( ptr )
	{}

	~smart_ptr()
	{
		delete ptr;
	}

	T& operator*()const
	{
		return *ptr;
	}

	T* operator->()const
	{
		return ptr;
	}
};

実際に使ってみます。ちなみに私が使用しているコンパイラVC++2008ExpressEditionです。

#include <crtdbg.h>

class Hoge
{
public:
	void func()
	{
		cout << "hoge" << endl;
	}
};

int main()
{
	//メモリリーク検出
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

	smart_ptr< int > a( new int( 1 ) );
	smart_ptr< Hoge > b( new Hoge() );

	cout << *a << endl;
	b->func();

	return 0;
}

メモリリークせずにしっかりデストラクタでdeleteされてますね。

しかし、ここで問題が出てきます。
以下のようにsmart_ptr間でコピーを行うとどうなるでしょうか?

	smart_ptr< int > a( new int( 1 ) );
	smart_ptr< int > b = a;

VCでは「Debug Assertion Failed!」とメッセージボックスが出ますね。
次回はこの問題を解決してみます。