お勉強がてらに参照カウンタを持ったスマートポインタを実装してみました。
#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
循環参照の問題がよくわからないので実装できないまま、とりあえず参照カウントするだけ・・・
勢いで実装したから何か不都合がありそう。