/*! * bnf::Ptr * * Copyright (c) 2007 tkuri {at} fat.coara.or.jp */ #ifndef BNF_PTR_HPP_ #define BNF_PTR_HPP_ /* * 特製スマートポインタ * * boost::shared_ptr が使える場合は * そちらを使った方がいいと思います. */ namespace bnf { struct Counter { int count; Counter(): count(1) { } }; /*! * スマートポインタ */ template struct Ptr { void release_ptr() { if (ctr_ && --ctr_->count == 0) { delete ptr_; delete ctr_; } ptr_ = 0; ctr_ = 0; } public: Counter* ctr_; T* ptr_; /*! * コンストラクタ */ Ptr(): ctr_(0), ptr_(0) { } /*! * 生のポインタからのコンストラクタ */ Ptr(T* ptr): ctr_(0), ptr_(0) { if (ptr) { ptr_ = ptr; ctr_ = new Counter(); } } template explicit Ptr(D* ptr): ctr_(0), ptr_(0) { if (ptr) { ptr_ = ptr; ctr_ = new Counter(); } } /*! * コピーコンストラクタ */ Ptr(const Ptr& another): ctr_(0), ptr_(0) { *this = another; } template explicit Ptr(const Ptr& another): ctr_(0), ptr_(0) { *this = another; } /*! * デストラクタ */ ~Ptr() { if (ctr_) { release_ptr(); } else { delete ptr_; // コンストラクタ内で例外が出た場合,ここに来るかも } } /*! * ポインタ値 */ operator void * () const { return ptr_; } /*! * 代入演算子 */ template Ptr& operator = (D* ptr) { if (ptr_ != ptr) { release_ptr(); if (ptr) { ptr_ = ptr; ctr_ = new Counter(); } } return *this; } /*! * 代入演算子 */ Ptr& operator = (const Ptr& another) { if (another.ptr_ != this->ptr_) { release_ptr(); ptr_ = another.ptr_; ctr_ = another.ctr_; if (ctr_) { ctr_->count++; } } return *this; } template Ptr& operator = (const Ptr& another) { if (another.ptr_ != this->ptr_) { release_ptr(); ptr_ = another.ptr_; ctr_ = another.ctr_; if (ctr_) { ctr_->count++; } } return *this; } /*! * 演算子 "->" */ const T * operator ->() const { return ptr_; } /*! * 演算子 "->" */ T * operator -> () { return ptr_; } }; } // end of namespace #endif // BNF_PTR_HPP_