通过强引用和弱引用实现的自动内存管理预想,仅实现了管理内存的部分,仍有许多C++11的功能未能实现。
SharedPtr => std::shared_ptr
SentinelPtr => std::weak_ptr
templateclass SentinelPtr; template class SharedPtr { size_t* ref_counter_ = nullptr;// 强引用计数器 T* val_ = nullptr; // 值引用 size_t * soft_ref_counter_ = nullptr; // 弱引用计数器 // template friend class SentinelPtr ; public: SharedPtr operator=(const SharedPtr& rhs) = delete; SharedPtr():ref_counter_(nullptr), val_(nullptr), soft_ref_counter_(nullptr){ } SharedPtr(T val) :val_(new T(val)), ref_counter_(new size_t(1)), soft_ref_counter_(new size_t(1)) { } SharedPtr(T* val_pointer) { if (val_pointer != nullptr) { val_ = val_pointer; ref_counter_ = new size_t(1); soft_ref_counter_ = new size_t(1); } else { val_ = nullptr; ref_counter_ = nullptr; soft_ref_counter_ = nullptr; } } SharedPtr(const SharedPtr & rhs) { // 歧义: 引用计数本身必须自增,const的表达有点奇怪 if(val_ != rhs.val_) try_release(); soft_ref_counter_ = rhs.soft_ref_counter_; ref_counter_ = rhs.ref_counter_; val_ = rhs.val_; // rhs通过默认构造的 if (val_ == nullptr) return; assert(soft_ref_counter_ != nullptr); assert(ref_counter_ != nullptr); (*soft_ref_counter_)++; (*ref_counter_)++; } ~SharedPtr() { if (val_ == nullptr) return; assert(ref_counter_ != nullptr); assert(val_ != nullptr); try_release(); soft_ref_counter_ = nullptr; ref_counter_ = nullptr; val_ = nullptr; } public: size_t use_count()const { if (ref_counter_) return *ref_counter_; return 0; } private: // 释放了val就return true void try_release() { // 可能通过空指针构造的对象 if (!soft_ref_counter_) return; // 弱引用计数, 后面再一起结算 (*soft_ref_counter_)--; assert(ref_counter_ != nullptr); (*ref_counter_)--; // 强引用计数为0, 释放值 if (*ref_counter_ == 0) { delete val_; val_ = nullptr; } // 弱引用计数为0, 释放所有计数器 if ((*soft_ref_counter_) == 0) { delete ref_counter_; delete soft_ref_counter_; ref_counter_ = nullptr; soft_ref_counter_ = nullptr; } } }; template class SentinelPtr { size_t* ref_counter_; // 强引用计数器 size_t* soft_ref_counter_; // 弱引用计数器(相当于强引用器的引用计数) T* val_; // 提升值 public: SharedPtr update() { if (!soft_ref_counter_ || !ref_counter_) return SharedPtr ; SharedPtr ex; ex.ref_counter_ = ref_counter_; ex.soft_ref_counter_ = soft_ref_counter_; ex.val_ = val_; (*soft_ref_counter_)++; (*ref_counter_)++; return ex; } SentinelPtr(SharedPtr sha_ptr) { ref_counter_ = sha_ptr.ref_counter_; soft_ref_counter_ = sha_ptr.soft_ref_counter_; val_ = sha_ptr.val_; if (soft_ref_counter_) { assert(ref_counter_ != nullptr); (*soft_ref_counter_)++; } else { assert(ref_counter_ == nullptr); assert(soft_ref_counter_ == nullptr); assert(val_ == nullptr); } } SentinelPtr(const SentinelPtr & st_ptr) { if(soft_ref_counter_ != st_ptr) try_release(); ref_counter_ = st_ptr.ref_counter_; soft_ref_counter_ = st_ptr.soft_ref_counter_; val_ = st_ptr.val_; if (soft_ref_counter_) { assert(ref_counter_ != nullptr); (*soft_ref_counter_)++; } else { assert(ref_counter_ == nullptr); assert(soft_ref_counter_ == nullptr); assert(val_ == nullptr); } } ~SentinelPtr() { try_release(); ref_counter_ = nullptr; val_ = nullptr; soft_ref_counter_ = nullptr; } private: void try_release() { if (!soft_ref_counter_) return; assert(ref_counter_ != nullptr); (*soft_ref_counter_)--; if (*soft_ref_counter_ == 0) { delete soft_ref_counter_; delete ref_counter_; soft_ref_counter_ = nullptr; ref_counter_ = nullptr; } } }; int main() { // default ctor { SharedPtr emp_ptr; } // ctor(val) { SharedPtr ptr(4); assert(ptr.use_count() == 1); } // ctor(valpointer) { SharedPtr b(new int(4)); assert(b.use_count() == 1); } // dctr { SharedPtr outer(4); { SharedPtr inner(outer); assert(outer.use_count() == inner.use_count()); assert(inner.use_count() == 2); } assert(outer.use_count() == 1); } { SharedPtr outer(4); SentinelPtr p = outer; assert(outer.use_count() == 1); } return 0; }



