参照カウントと削除子の二つ分もメモリ確保してるのはちょっと勿体ないなぁ というか,よく考えてみると,この二つは同じ寿命なので一つにまとめても 良さそうです.
ということで参照カウントと削除子を両方管理するような shared_count
クラスを用意してみたバージョンがこんな感じ.
struct shared_count { long count_; shared_count() :count_(1) {} void increment() { ++count_; } void decrement(void* p) { if (--count_ == 0) { release(p); delete this; } } virtual void release(void*) const = 0; }; template <typename T> struct shared_count_default :public shared_count { virtual void release(void* p) const { delete reinterpret_cast<T*>(p); } }; template <typename T> class shared_ptr { T* ptr_; shared_count* count_; public: typedef T element_type; shared_ptr() :ptr_(0), count_(0) {} ~shared_ptr() { if (count_) { count_->decrement(ptr_); } } template <typename Y> explicit shared_ptr(Y* p) :ptr_(p), count_(new shared_count_default<Y>) { } shared_ptr(const shared_ptr& r) :ptr_(r.ptr_), count_(r.count_) { if (count_) { count_->increment(); } } shared_ptr& operator = (const shared_ptr& r) { if (count_ != r.count_) { shared_ptr(r).swap(*this); } return *this; } T& operator * () const { return *ptr_;} T* operator -> () const { return ptr_; } long use_count() const { return count_ ? count_->count_ : 0; } T* get() const { return ptr_; } void swap(shared_ptr& r) { std::swap(ptr_, r.ptr_); std::swap(count_, r.count_); } void reset() { shared_ptr().swap(*this); } };
意味的に increment
, decrement
の処理は shared_count
側だろう思っ
て移しましたけど,そうすると decrement
にポインタを渡さないといけな
くなってしまい,これはこれでちょっと意味が変な気もします.モヤモヤ
0 件のコメント:
コメントを投稿