简单智能指针的实现
#include<iostream>
using namespace std;
// 智能指针 保证能做到资源的自动释放!!!
// 利用栈上的对象出作用域自动释放
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr=nullptr)
{
mptr=ptr;
}
~CSmartPtr()
{
delete mptr;
}
T& operator*()
{
return *mptr;
}
T *operator->(){ return mptr;}
private:
T *mptr;
};
int main()
{
// int *p=new int;
CSmartPtr<int> ptr1(new int);
*ptr1=20;
class Test
{
public:
void test() {cout<<"call Test::test"<<endl;}
};
CSmartPtr<Test> ptr2(new Test());
ptr2->test();
cout<<"123"<<endl;
return 0;
}
不带引用计数的智能指针
auto_ptr
实现带引用计数的智能指针
#include<iostream>
#include<memory>
using namespace std;
// 对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:
RefCnt(T *ptr=nullptr)
{
mptr=ptr;
if(mptr!=nullptr)
{
mcount=1;
}
else{
mcount=0;
}
}
void addRef()
{
// 添加资源的引用计数
mcount++;
}
int delRef()
{
// 添加资源的引用计数
return --mcount;
}
private:
T *mptr;
int mcount;
};
// 智能指针 保证能做到资源的自动释放!!!
// 利用栈上的对象出作用域自动释放
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr=nullptr)
{
mptr=ptr;
mpRefCnt=new RefCnt<T>(mptr);
}
CSmartPtr(const CSmartPtr<T>&src)
{
mptr=new T(*src.mptr);
mpRefCnt=src.mpRefCnt;
if(mptr!=nullptr)
{
mpRefCnt->addRef();
}
}
CSmartPtr<T> &operator=(const CSmartPtr<T>&src)
{
if(this==&src)
{
return *this;
}
if(0==mpRefCnt->delRef())
{
delete mptr;
}
mptr=src.mptr;
mpRefCnt=src.mpRefCnt;
mpRefCnt->addRef();
return *this;
}
~CSmartPtr()
{
if(0==mpRefCnt->delRef())
{
mptr=nullptr;
delete mptr;
}
}
T& operator*()
{
return *mptr;
}
T *operator->(){ return mptr;}
private:
T *mptr; //指向资源的指针
RefCnt<T> *mpRefCnt; //指向该资源引用计数的指针
};
int main()
{
/*
带引用计数的智能指针share_ptr和weak_ptr
带引用计树:多个指针指针可以管理同一个资源
带引用计数:给每一个对象资源匹配一个引用计数
智能指针-> 资源的时候->引用计数+1
智能指针->不使用资源的时候——>引用计数+1 !=0 资源释放了
*/
CSmartPtr<int> ptr1(new int);
CSmartPtr<int> ptr2(ptr1);
return 0;
}
交叉引用
#include<iostream>
#include<memory>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class B;
class A
{
public:
A()
{cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
shared_ptr<B> _ptrb;
};
class B
{
public:
B()
{cout<<"B()"<<endl;}
~B(){cout<<"~B()"<<endl;}
shared_ptr<A> _ptra;
};
int main(void)
{
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->_ptrb=pb;
pb->_ptra=pa;
cout<<pa.use_count()<<endl; //2
cout<<pa.use_count()<<endl; //2
return 0;
}
解决
#include<iostream>
#include<memory>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class B;
class A
{
public:
A()
{cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
void testA() {cout<<"非常好用的方法"<<endl;}
weak_ptr<B> _ptrb;
};
class B
{
public:
B()
{cout<<"B()"<<endl;}
~B(){cout<<"~B()"<<endl;}
void func()
{
shared_ptr<A> ps=_ptra.lock(); //提升方法
if(ps!=nullptr)
{
// _ptra->testA();
shared_ptr<A> ps=_ptra.lock(); //提升方法
ps->testA();
}
}
weak_ptr<A> _ptra;
};
int main(void)
{
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->_ptrb=pb;
pb->_ptra=pa;
cout<<pa.use_count()<<endl; //1
cout<<pa.use_count()<<endl; //1
return 0;
}
解决交叉引用
#include<iostream>
#include<memory>
#include<thread>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class A
{
public:
A()
{cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
void testA() {cout<<"非常好用的方法"<<endl;}
};
void handler01(weak_ptr<A> pw)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
shared_ptr<A> sp=pw.lock();
if(sp!=nullptr)
{
sp->testA();
}
else{
cout<<"A对象已经析构不能访问"<<endl;
}
}
// main线程
int main()
{
{
shared_ptr<A> p(new A());
thread t1(handler01,weak_ptr<A>(p));
t1.detach();
std::this_thread::sleep_for(std::chrono::seconds(2));
}
std::this_thread::sleep_for(std::chrono::seconds(4));
// 阻塞等待子线程结束
// t1.join();
return 0;
}
删除器
#include<iostream>
#include<memory>
#include<thread>
#include<functional>
using namespace std;
template<typename T>
class MyDeletor
{
public:
void operator()(T *ptr) const
{
cout<<"call MyDeletor operator[]"<<endl;
delete []ptr;
}
};
template<typename T>
class MyFileDeletor
{
public:
void operator()(T*ptr) const
{
cout<<"call MyfileDeletor.operator"<<endl;
fclose(ptr);
}
};
int main()
{
unique_ptr<int,MyDeletor<int>> ptr1(new int[100]); //de;ete []ptr
unique_ptr<FILE,MyFileDeletor<FILE>> ptr2(fopen("data.txt","w"));
// lambda表达式
unique_ptr<int,function<void(int*)>> ptr3(new int[100],[](int *p)->void{
delete p;
});
unique_ptr<FILE,function<void (FILE*)>> ptr4(fopen("data1.txt","w"),[](FILE*p)->void{
delete p;
} );
return 0;
}