スマートポインタ

お勉強がてらに参照カウンタを持ったスマートポインタを実装してみました。

#include <iostream>
#include <string>

template<class T>
class SmartPointer{

private:
	T * m_pointer;
	size_t * m_count;
	
	// 今まで参照していたものを破棄
	inline void destruction(){
		if(--(*m_count) == 0){
			std::cout << "delete: " << **this << std::endl;
			delete m_pointer; delete m_count;
			m_pointer =NULL; m_count = NULL; 
		}
	}
	
public:
	inline const size_t count() const{ return m_count ? *m_count : 0; }
	inline T * get() const{ return m_count ? m_pointer : NULL; }
	inline T * operator -> () const { return m_pointer; }
	inline T & operator * () const { return *m_pointer; }
	
	explicit SmartPointer()               : m_pointer(new T())     , m_count(new size_t(1)){ };
	explicit SmartPointer(const T & data) : m_pointer(new T(data)) , m_count(new size_t(1)){ };
	explicit SmartPointer(T * data)       : m_pointer(data)         , m_count(new size_t(1)){ };
	SmartPointer(const SmartPointer<T> & smart) : m_pointer(smart.m_pointer) , m_count(smart.m_count){
		++(*m_count);
	}
	
	SmartPointer<T> & operator=(const SmartPointer<T> &rhs){
		destruction();
		m_pointer = rhs.m_pointer;
		m_count = rhs.m_count;
		++(*m_count);
		return *this;
	}
	SmartPointer<T> & operator=(const T &rhs){ return *this = SmartPointer(rhs); }
	SmartPointer<T> & operator=(T * rhs){ return *this = SmartPointer(rhs); }
	
	~SmartPointer(){ destruction(); }
};



typedef SmartPointer<std::string> pstring;

void function(pstring ps){ // わざと値渡し
	std::cout << "function(ps) ps= " << *ps << std::endl;
	*ps = "function";
}

int main(){
	pstring s1("s1");
	pstring tmp("tmp");
	
	std::cout << "s1= " << *s1 << std::endl;
	{
		pstring s2("s2");
		tmp = s2;
	}
	std::cout << "tmp= " << *tmp << std::endl;
	
	pstring tmp2("tmp2");
	function(tmp2);
	std::cout << "tmp2= " << *tmp2 << std::endl;
	
}

s1= s1
delete: tmp
tmp= s2
function(ps) ps= tmp2
tmp2= function
delete: function
delete: s2
delete: s1


循環参照の問題がよくわからないので実装できないまま、とりあえず参照カウントするだけ・・・
勢いで実装したから何か不都合がありそう。