shared_ptr(共享智能指针)
和独立智能指针区别,它的对象可以被多个指针指向
先是一个对象里面有ptr和删除器,ptr指向一个对象,对象面有计数器ref,和指向对象的指针。
#ifndef MY_SHARED_PTR_H
#define MY_SHARED_PTR_H
#include<atomic>
template<class _Ty>
class MyDeletor
{
public:
//MyDeletor() = default;
MyDeletor() {}
void operator()(_Ty* ptr) const
{
if (ptr != nullptr)
{
delete ptr;
}
}
};
template<class _Ty>
class MyDeletor<_Ty[]>
{
public:
MyDeletor() = default;
void operator()(_Ty* ptr) const
{
if (ptr != nullptr)
{
delete[]ptr;
}
}
};
template<class _Ty>
class RefCnt
{
public:
_Ty* mptr;
//int ref;
std::atomic_int ref;
public:
RefCnt(_Ty* p = nullptr) :mptr(p), ref(mptr != nullptr) {}
~RefCnt() {}
};
template<class _Ty, class _Dx = MyDeletor<_Ty> >
class my_shared_ptr // thread;
{
public:
my_shared_ptr(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt(p);
}
}
my_shared_ptr(const my_shared_ptr& _Y) :ptr(_Y.ptr)
{
if (ptr != nullptr)
{
ptr->ref += 1;
}
}// my_shared_ptr<Object> op2(op1);
my_shared_ptr(my_shared_ptr&& _Y) :ptr(_Y.ptr)
{
_Y.ptr = nullptr;
}// my_shared_ptr<Object> op2(std::move(op1));
operator bool() const { return ptr != nullptr; }
my_shared_ptr& operator=(const my_shared_ptr& _Y) //
{
if (this == &_Y || this->ptr == _Y.ptr) return *this;
if (ptr != NULL && --ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = _Y.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
my_shared_ptr& operator=(my_shared_ptr&& _Y) // move operator =
{
if (this == &_Y) return *this;
if (this->ptr == _Y.ptr && this->ptr != nullptr && _Y.ptr != nullptr)
{
this->ptr->ref -= 1;
_Y.ptr = nullptr;
return *this;
}
if (this->ptr != nullptr && --ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = _Y.ptr;
_Y.ptr = nullptr;
return *this;
}
void reset(_Ty* p = nullptr)
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = new RefCnt<_Ty>(p);
}
~my_shared_ptr()
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
_Ty* get() const { return ptr->mptr; }
_Ty& operator*() const
{
return *get();
}
_Ty* operator->() const
{
return get();
}
size_t use_count() const
{
if (this->ptr == nullptr) return 0;
return this->ptr->ref;
}
void swap(my_shared_ptr& r)
{
std::swap(this->ptr, r.ptr);
}
private:
RefCnt<_Ty>* ptr;
_Dx mDeletor;
};
template<class _Ty, class _Dx >
class my_shared_ptr<_Ty[], _Dx>
{
public:
my_shared_ptr(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt(p);
}
}
my_shared_ptr(const my_shared_ptr& _Y) :ptr(_Y.ptr)
{
if (ptr != nullptr)
{
ptr->ref += 1;
}
}// my_shared_ptr<Object> op2(op1);
my_shared_ptr(my_shared_ptr&& _Y) :ptr(_Y.ptr)
{
_Y.ptr = nullptr;
}// my_shared_ptr<Object> op2(std::move(op1));
operator bool() const { return ptr != nullptr; }
my_shared_ptr& operator=(const my_shared_ptr& _Y) //
{
if (this == &_Y || this->ptr == _Y.ptr) return *this;
if (ptr != NULL && --ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = _Y.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
my_shared_ptr& operator=(my_shared_ptr&& _Y) // move operator =
{
if (this == &_Y) return *this;
if (this->ptr == _Y.ptr && this->ptr != nullptr && _Y.ptr != nullptr)
{
this->ptr->ref -= 1;
_Y.ptr = nullptr;
return *this;
}
if (this->ptr != nullptr && --ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = _Y.ptr;
_Y.ptr = nullptr;
return *this;
}
void reset(_Ty* p = nullptr)
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = new RefCnt<_Ty>(p);
}
~my_shared_ptr()
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
_Ty* get() const { return ptr->mptr; }
_Ty& operator*() const
{
return *get();
}
_Ty* operator->() const
{
return get();
}
size_t use_count() const
{
if (this->ptr == nullptr) return 0;
return this->ptr->ref;
}
void swap(my_shared_ptr& r)
{
std::swap(this->ptr, r.ptr);
}
_Ty& operator[](const int idx) const
{
return ptr->mptr[idx];
}
private:
RefCnt<_Ty>* ptr;
_Dx mDeletor;
};
#endif