0.前言
C++11
为我们带来了std::shared_ptr
,方便我们在动态分配内存的时候发生memory leak,他是基于引用计数实现的,下面给出一个简化版本。
1.实现
namespace smart_ptr {
class counter {
public:
counter(unsigned cnt):count_(cnt) {
}
unsigned& operator++() {
++count_;
return count_;
}
unsigned operator++(int) {
unsigned count = count_;
++count_;
return count;
}
unsigned& operator--() {
--count_;
return count_;
}
unsigned operator--(int) {
unsigned count = count_;
--count_;
return count;
}
unsigned getCount()const {
return count_;
}
private:
unsigned count_ = 0;
};
template<typename T>
class shared_ptr {
public:
using pointer=T *;
using reference=T &;
shared_ptr(pointer ptr) {
counter_ = new counter(1);
data_ = ptr;
}
~shared_ptr() {
--(*counter_);
if (counter_->getCount() == 0) {
delete data_;
data_ = nullptr;
delete counter_;
counter_ = nullptr;
}
}
shared_ptr(const shared_ptr<T>& s_ptr) {
counter_ = s_ptr.counter_;
++(*counter_);
data_ = s_ptr.data_;
}
pointer get()const {
return data_;
}
unsigned use_count()const {
return counter_->count_;
}
pointer operator->() {
return data_;
}
reference operator*() {
return *data_;
}
private:
counter* counter_;
pointer data_;
};
}
在这里我们声明了一个类counter
专门用于计算指向动态内存的对象数量,在我们撞见shared_ptr
对象时,动态分配一个内存给成员counter_
,当对象发生拷贝时,使用同一个counter
增加引用计数。在析构时,我们将counter
进行自减,如果自减后counter
为零,那么就释放动态分配的内存。也就是说,如果我们想要像new
操作符一样手动析构,那么我们只需要手动调用~shared_ptr()
即可。手动调用析构函数只是销毁了对象,并没有释放这段内存。
网友评论