智能指针简单实现
原理
- RAII特性,利用对象生命周期控制程序资源的简单技术
- 重载 operator * 和 operator -> ,具体指针一样的行为
auto_ptr指针
- auto_ptr 缺点是 当对象被拷贝或者赋值后,前面的对象就悬空了。
auto_ptr 模拟实现
template <class T>
class Auto_ptr{
public:
Auto_ptr(T* ptr=nullptr):_ptr(ptr){}
~Auto_ptr() { if(_ptr) delete _ptr;}
//拷贝构造会释放s对象的指针,造成s指针与管理对象断开联系
Auto_ptr(Auto_ptr<T> &s):_ptr(s._ptr) {
s._ptr = NULL;
}
Auto_ptr<T>& operator = (Auto_ptr<T> &s){
if(this != &s._ptr) {
if(_ptr) delete _ptr;
_ptr = s._ptr;
s._ptr = NULL;
}
return *this;
}
T& operator*() {
return *_ptr;
}
T* operator->(){
return _ptr;
}
private:
T* _ptr;
}
unique_ptr
- unique_ptr 的实现原理,简单粗暴防拷贝,下面简化实现
template<class T>
class Unique_ptr{
Unique_ptr(T* ptr=nullptr):_ptr(ptr){}
~Unique_ptr(){if(_ptr) delete _ptr;}
T& operator*(){ return *_ptr;}
T* operator->() {return _ptr;}
private:
Unique_ptr(Unique_ptr<T> &s):_ptr(s._ptr){s._ptr=NULL}
Unique_ptr<T>& operator=(Unique_ptr<T> &s){
if(this != &s._ptr){
if(_ptr) delete _ptr;
_ptr = s._ptr;
s._ptr = NULL;
}
return *this;
}
private:
T* _ptr;
}
share_ptr
share_ptr 的原理: 通过引用计数老实现多个share_ptr 对象之间的共享资源。
- share_ptr内部,给每个资源维护了一份计数,用来记录该资源被几个对象共享。
- 在对象被销货时(析构函数调用) 就说明自己不适用资源了,对象引用计数减一
- 如果引用计数是0 必须释放资源
- 如果引用计数不是0,说明还有其他对象在使用资源 不能释放。
template<calss T>
class Share_ptr{
private:
T* _ptr;
int* _pRefCount;
mutex _pMutex
public:
Shared_ptr(T* ptr) : _ptr(ptr),_pMutex(new mutex),_pRefCount(new int(1)) {}
~Shared_ptr() { release(); }
Share_ptr(const Shared_ptr<T>& sp) { AddRedCOunt(); }
SHare_ptr<T>* operator=(const Shared_ptr<T>& sp) {
if (this != sp) {
Realse();
_ptr = sp._ptr;
_pRefCount = sp._pRefConut;
_pMutex = sp._pMutex;
AddRefCount();
}
return this;
}
T& operator*() { return *_ptr; }
T* operator->() { return _ptr; }
int UseCount() { return *_pRefCount ;}
T* Get() { return _ptr; }
void AddRefcount(){
_pMutex.lock();
++(*_pRefCount);
_pMutex.unlock();
}
private:
void Release (){
bool flag = false;
_pMutex.lock();
if (--(*_pRefCount) == 0) {
delete _pRefCount;
delete _ptr;
flag = true
}
_pMutex.unlock();
if (flag == true) delete _pMutex;
}
}
测试程序
#include<iostream>
#include<memory>
using namespace std;
struct ListNode
{
int _data;
ListNode(int n):_data(n){ cout << "construct ListNode:" << _data << endl; }
weak_ptr<ListNode> _prev;
weak_ptr<ListNode> _next;
~ListNode(){ cout << "~ListNode"<< _data <<"()"<< endl; }
};
int main()
{
shared_ptr<ListNode> node1(new ListNode(1));
shared_ptr<ListNode> node2(new ListNode(2));
shared_ptr<ListNode> node3 = node1;
shared_ptr<ListNode> node4 = node1;
cout << "node1 usecount:"<<node1.use_count() << endl;
cout << "node2 usecount:"<<node2.use_count() << endl;
cout << "node3 usecount:"<<node3.use_count() << endl;
node1->_next = node2;
node2->_prev = node1;
cout << "node1 usecount:"<<node1.use_count() << endl;
cout << "node2 usecount:"<<node2.use_count() << endl;
cout << "node3 usecount:"<<node3.use_count() << endl;
//system("pause");
return 0;
}