template<typename T>
class my_shared_ptr{
public:
explicit my_shared_ptr(T* p=nullptr){
m_p = p;
m_cnt = new size_t(1);
m_mutex = new mutex();
}
my_shared_ptr(const my_shared_ptr& other){
m_p = other.m_p;
m_cnt = other.m_cnt;
m_mutex = other.m_mutex;
acquire();
}
my_shared_ptr& operator=(const my_shared_ptr& other){
if(m_p==other.m_p)
return *this;
release();
m_p = other.m_p;
m_cnt = other.m_cnt;
m_mutex = other.m_mutex;
acquire();
return *this;
}
my_shared_ptr(my_shared_ptr&& o){
m_p = o.m_p;
m_cnt = o.m_cnt;
m_mutex = o.m_mutex;
o.m_p = nullptr;
o.m_cnt = new size_t(1);
o.m_mutex = new mutex();
}
my_shared_ptr& operator=(my_shared_ptr&& o){
if(m_p==o.m_p)
return *this;
release();
m_p = o.m_p;
m_cnt = o.m_cnt;
m_mutex = o.m_mutex;
o.m_p = nullptr;
o.m_cnt = new size_t(1);
o.m_mutex = new mutex();
return *this;
}
size_t use_count() const{
return *m_cnt;
}
~my_shared_ptr(){
release();
}
T* get() const{
return m_p;
}
T& operator*() const{
return *m_p;
}
T* operator->() const{
return m_p;
}
private:
void acquire(){
m_mutex->lock();
++(*m_cnt);
m_mutex->unlock();
}
void release(){
bool deleted = false;
m_mutex->lock();
--(*m_cnt);
if(*m_cnt==0){
deleted = true;
delete m_cnt;
if(m_p!=nullptr)
delete m_p;
}
m_mutex->unlock();
if(deleted){
delete m_mutex;
}
}
size_t *m_cnt;
T *m_p;
mutex* m_mutex;
};