智能指针篇 ——复刻
智能指针篇 ——复刻
1.myunique -unique_ptr
//复刻unique_ptr
//功能:
//删除拷贝构造和等号运算符构造,
//构造,析构,
//右值拷贝构造和右值等号运算符构造,relese(),reset(),
//get(),*,->,
//获取删除器类型,交换指针
//[](选)
template<typename _Ty>
class Del
{
public:
Del() {}
void operator()(_Ty* ptr)
{
if (ptr != nullptr)
{
delete ptr;
}
}
};
template<typename _Ty>
class Del<_Ty[]>
{
public:
Del() = default;
void operator()(_Ty* ptr)
{
if (ptr != nullptr)
{
delete[] ptr;
}
}
};
template<class _Ty, class _De = Del<_Ty>>
class myunique
{
public:
_Ty* ptr;
_De Deletor;
using point = _Ty*;
using elem = _Ty;
using Deletortype = _De;
myunique(const myunique&) = delete;
myunique& operator=(const myunique&) = delete;
myunique(_Ty* p):ptr(p) {}
~myunique()
{
if (ptr != nullptr)
{
Deletor(ptr);
ptr = nullptr;
}
}
myunique(const myunique&& R)
{
//这里不太熟悉
reset(R.release());
}
myunique& operator=(const myunique&& R)
{
if (this != &R)
{
reset(R.release());
}
return *this;
}
point release()
{
//这里不太熟悉
_Ty old = ptr;
ptr = nullptr;
return old;
}
void reset(_Ty p)
{
_Ty old = ptr;
ptr = p;
if (old != nullptr) Deletor(old);
}
point get()
{
return ptr;
}
point operator->()
{
return get();
}
elem& operator*()
{
return *get();
}
Deletortype getDel()
{
return Deletor;
}
const Deletortype getDel() const
{
return Deletor;
}
void myswap(myunique& L)
{
std::swap(ptr, L.ptr);
}
};
template<class _Ty, class _De>
class myunique<_Ty[], _De>
{
public:
_Ty* ptr;
_De Deletor;
using point = _Ty*;
using elem = _Ty;
using Deletortype = _De;
myunique(const myunique&) = delete;
myunique& operator=(const myunique&) = delete;
myunique(point p):ptr(p) {}
~myunique()
{
if (ptr != nullptr)
{
Deletor(ptr);
ptr = nullptr;
}
}
myunique(const myunique&& R)
{
reset(R.release());
}
myunique& operator=(const myunique&& R)
{
if (this != &R)
{
reset(R.release());
}
return *this;
}
point release()
{
point old = ptr;
ptr = nullptr;
return old;
}
void reset(point p)
{
point old = ptr;
ptr = p;
if (old != nullptr) Deletor(old);
}
point get()
{
return ptr;
}
point operator->() const
{
return get();
}
elem& operator*() const
{
return *get();
}
elem& operator[](size_t idx) const
{
return ptr[idx];
}
Deletortype getDel()
{
return Deletor;
}
void myswap(myunique& L)
{
std::swap(ptr, L.ptr);
}
};
//测试用例的类型
class Obj
{
public:
int val;
//注意这里参数要给默认值
Obj(int n = 0) :val(n) { cout << "Obj()" << endl; }
~Obj() { cout << "~Obj()" << endl; }
};
int main()
{
myunique<Obj, Del<Obj>> p1(new Obj(10));
cout << (p1.operator*()).val << endl;
cout << (*p1).val << endl;
cout << "###############################" << endl;
myunique<Obj[], Del<Obj[]>> p2(new Obj[3]);
return 0;
}
2.myshared -shared_ptr
//复刻shared_ptr
//功能:
//构造,析构
//拷贝构造,赋值构造
//拷贝构造,赋值构造(右值)
// use_count()
//get(),*,->
//reset()
//myswap()
#include <atomic>
template<typename _Ty>
class Del
{
public:
Del() {}
void operator()(_Ty* p)
{
if (p != nullptr) delete p;
}
};
template<typename _Ty>
class Del<_Ty[]>
{
public:
Del() {}
void operator()(_Ty* p)
{
if (p != nullptr) delete[] p;
}
};
template<typename _Ty>
class RefCnt
{
public:
_Ty* mptr;
std::atomic_int ref;
RefCnt(_Ty* p = nullptr):mptr(p),ref(mptr != nullptr) {}
~RefCnt() {}
};
template<class _Ty, class _De = Del<_Ty>>
class myshared
{
public:
RefCnt<_Ty>* ptr;
_De Deletor;
myshared(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt<_Ty>(p);
}
}
~myshared()
{
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
myshared(myshared& L):ptr(L.ptr)
{
if (ptr != nullptr) ptr->ref += 1;
}
myshared& operator=(myshared& L)
{
if (this == &L || ptr == L.ptr) return *this;
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = L.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
//注意这里R为非const,因为会修改R
myshared(myshared&& R) :ptr(R.ptr)
{
R.ptr = nullptr;
}
myshared& operator=(myshared&& R)
{
if (this == &R) return *this;
if (ptr == R.ptr && ptr != nullptr)
{
ptr->ref -= 1;
R.ptr = nullptr;
return *this;
}
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete(ptr);
}
ptr = R.ptr;
R.ptr = nullptr;
return *this;
}
size_t use_count() const
{
if (ptr == nullptr) return 0;
return ptr->ref;
}
void myswap(myshared& L)
{
std::swap(ptr, L.ptr);
}
void reset(_Ty* p)
{
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = new RefCnt<_Ty>(p);
}
_Ty* get() const
{
return ptr->mptr;
}
_Ty* operator->() const
{
return get();
}
_Ty& operator*() const
{
return *get();
}
};
template<class _Ty, class _De>
class myshared<_Ty[],_De>
{
public:
RefCnt<_Ty>* ptr;
_De Deletor;
myshared(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt<_Ty>(p);
}
}
~myshared()
{
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
myshared(myshared& L) :ptr(L.ptr)
{
if (ptr != nullptr) ptr->ref += 1;
}
myshared& operator=(myshared& L)
{
if (this == &L || ptr == L.ptr) return *this;
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = L.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
myshared(myshared&& R) :ptr(R.ptr)
{
R.ptr = nullptr;
}
myshared& operator=(myshared&& R)
{
if (this == &R) return *this;
if (ptr == R.ptr && ptr != nullptr)
{
ptr->ref -= 1;
R.ptr = nullptr;
return *this;
}
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete(ptr);
}
ptr = R.ptr;
R.ptr = nullptr;
return *this;
}
size_t use_count() const
{
if (ptr == nullptr) return 0;
return ptr->ref;
}
void myswap(myshared& L)
{
std::swap(ptr, L.ptr);
}
void reset(_Ty* p)
{
if (ptr != nullptr && --ptr->ref == 0)
{
Deletor(ptr->mptr);
delete ptr;
}
ptr = new RefCnt<_Ty>(p);
}
_Ty* get() const
{
return ptr->mptr;
}
_Ty* operator->() const
{
return get();
}
_Ty& operator*() const
{
return *get();
}
_Ty& operator[](size_t idx)const
{
return ptr[idx];
}
};
class object
{
private:
int value;
public:
object(int x = 0) : value(x)
{
cout << "object()" << endl;
}
~object()
{
cout << "~object" << endl;
}
};
int main()
{
myshared<object> sp1(new object(10));
myshared<object> sp2(sp1);
cout << sp1.use_count() << endl;
myshared<object> sp3(std::move(sp1));
cout << sp3.use_count() << endl;
}