我们今天来实现一个简易版的智能指针吧!拖了好久啦,以后会把vector、string的简易版也给补上,gigigi
我们可以先想想shared_ptr
最大的特点,就是当他的引用计数为0时,便会自动释放所指对象和析构。所以一个关键点就是这个引用计数怎么设置?static?不可以!static变量同属于一个类的所有对象,这样就会导致不管指的是不是同一个对象,引用计数都相同。所以我们这里决定采用一个指针来进行引用计数。具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <iostream> #include <mutex> #include <string>
template <typename T> class shared_ptr{ public: explicit shared_ptr(T* sPtr = nullptr): sPtr_(sPtr){ if(sPtr_){ useCount_ = new int(1); sMutex_ = new std::mutex; } }
~shared_ptr(){ release(); }
shared_ptr(const shared_ptr<T>& sp){ useCount_ = sp.useCount_; sPtr_ = sp.sPtr_; sMutex_ = sp.sMutex_; addUsecount(); }
shared_ptr<T>& operator=(const shared_ptr<T>& sp){ if(sPtr_ != sp.sPtr_){ release(); sPtr_ = sp.sPtr_; useCount_ = sp.useCount_; sMutex_ = sp.sMutex_; addUsecount(); } return *this; }
T& operator*(){ return *sPtr_; }
T* operator->(){ return sPtr_; }
int useCount(){ return *useCount_; }
T* get(){ return sPtr_; } private: void addUsecount(){ sMutex_->lock(); ++(*useCount_); sMutex_->unlock(); }
void release(){ bool deleteFlag = false; sMutex_->lock(); if(--(*useCount_) == 0){ delete useCount_; delete sPtr_; deleteFlag = true; } sMutex_->unlock(); if(deleteFlag){ delete sMutex_; } } private: int* useCount_; T* sPtr_; std::mutex* sMutex_; };
int main(){ shared_ptr<std::string> p1(new std::string("hello")); shared_ptr<std::string> p2 = p1; shared_ptr<std::string> p3(p2); std::cout << p3.useCount() << std::endl; std::cout << p2.useCount() << std::endl; p2 = p3; std::cout << p3.useCount() << std::endl; std::cout << p2.useCount() << std::endl; return 0; }
|
插入结果图片有点问题,最近没时间弄,各位自己跑一下验证一下,有错误记得说!!!