C++的四种智能指针及简单实现
参考:C++智能指针讲解及模拟实现
一、auto_ptr
- auto_ptr有拷贝语义,拷贝后源对象变为空指针,可能引发严重问题
template<class T>
class my_unique_ptr{
private:
T *_ptr;
public:
// 普通构造函数
my_unique_ptr(T *ptr) : _ptr(ptr){}
// 拷贝构造函数
my_unique_ptr(my_unique_ptr<T> a_ptr){
_ptr = a_ptr._ptr;
a_ptr._ptr = nullptr;
}
// 析构函数
~my_unique_ptr(){
if(_ptr){
delete _ptr;
_ptr = nullptr;
}
}
// 重载*运算符
T& operator*(){
return *_ptr;
}
// 重载->运算符
T* operator->(){
return _ptr;
}
// 重载=运算符
my_unique_ptr<T>& operator=(my_unique_ptr<T> a_ptr){
if(this != &a_ptr){
delete _ptr;
_ptr = a_ptr._ptr;
a_ptr.ptr = nullptr;
}
return *this;
}
};
二、unique_ptr
- 与auto_ptr类似,但是没有拷贝语义,但是允许使用移动语义
template<class T>
class my_unique_ptr{
private:
T *_ptr;
public:
// 普通构造函数
my_unique_ptr(T *ptr) : _ptr(ptr){}
// 拷贝构造函数
my_unique_ptr(my_unique_ptr<T> a_ptr)=delete;
// 析构函数
~my_unique_ptr(){
if(_ptr){
delete _ptr;
_ptr = nullptr;
}
}
// 重载*运算符
T& operator*(){
return *_ptr;
}
// 重载->运算符
T* operator->(){
return _ptr;
}
// 重载=运算符
my_unique_ptr<T>& operator=(my_unique_ptr<T> a_ptr)=delete;
public:
const T* get(){
return _ptr;
}
size_t use_count(){
return *_count;
}
};
三、shared_ptr
- 多个shared_ptr可以指向同一处资源,当所有shared_ptr被只放时,该处资源才被释放
template<class T>
class my_shared_ptr{
private:
T *_ptr;
int *_count;
public:
// 普通构造函数
my_shared_ptr(T *ptr) : _ptr(ptr), _count(new int(1)){}
// 拷贝构造函数
my_shared_ptr(my_shared_ptr<T> &s_ptr){
_ptr = s_ptr._ptr;
_count = s_ptr._count;
++(*_count);
}
// 析构函数
~my_shared_ptr(){
--(*_count);
if(0 == (*_count)){
if(_ptr){
delete _ptr;
}
delete _count;
}
}
// 重载*运算符
T& operator*(){
return *_ptr;
}
// 重载->运算符
T* operator->(){
return ptr;
}
// 重载=运算符
my_shared_ptr<T>& operator=(my_shared_ptr<T> u_ptr){
// 避免自己给自己赋值
if(_ptr != u_ptr._ptr){
// 减少原先指向对象的引用
--(*_count);
if(0 == (*_count)){
if(_ptr){
delete _ptr;
}
delete _count;
}
// 拷贝
_ptr = u_ptr._ptr;
_count = u_ptr._count;
++(*count);
}
}
};
四、weak_ptr
- weak_ptr是一种弱引用型指针,不控制所指向对象生存期的智能指针,主要为了解决循环引用问题和悬空指针问题
template<class T>
class my_weak_ptr
{
private:
T *_ptr;
size_t _shared_count;
public:
my_weak_ptr(const my_shared_ptr<T> &s_ptr) _ptr(s_ptr._ptr), _shared_count(s_ptr._count);
my_weak_ptr(const my_weak_ptr<T> &w_ptr) _ptr(w_ptr._ptr), _shared_count(s_ptr._shared_count);
// 重载*运算符
T& operator*()
{
return *_ptr;
}
// 重载->运算符
T* operator->()
{
return _ptr;
}
// 重载=运算符
my_weak_ptr<T>& operator=(const my_shared_ptr<T>& s_ptr)
{
_ptr = s_ptr.get();
return *this;
}
};