#include<iostream>
#include<memory>
using namespace std;
class Int {
private:
int _val;
public:
Int() :_val(0) { cout << "无参的构造函数" << endl; }
explicit Int(int val) :_val(val) {
cout << "Int()" << endl;
}
~Int() {
cout << "~Int()" << endl;
}
int& Value() {
return _val;
}
void PrintInt()const {
cout << _val << endl;
}
const int& Value()const {
cout << _val << endl;
}
Int& operator=(const Int& other) {
cout << "operator=()" << endl;
if (this != &other) {
this->_val = other._val;
}
return *this;
}
Int(const Int& other) :_val(other._val){
cout << "拷贝构造" << endl;
}
};
namespace yolo{
template<class _Ty>
struct my_default_deleter{
void operator()(_Ty* p)const {
delete p;
}
};
template<class _Ty>//专门针对数组的模板特化(为特定的类型提供特殊的实现)
struct my_default_deleter<_Ty[]> {
void operator()(_Ty* p)const {
delete[]p;
}
};
template<class _Ty,class _Dx = my_default_deleter<_Ty> >
class uniquePtr {
public:
using element_type = _Ty;
using pointer = _Ty*;
using deleter_type = _Dx;
private:
pointer mPtr;
deleter_type mDeleter;
public:
uniquePtr(const uniquePtr&) = delete;//unique_ptr没有拷贝构造和赋值
uniquePtr& operator=(const uniquePtr&) = delete;
uniquePtr(uniquePtr&& other) {//移动构造不要写const uniquePtr&&other,因为你要动他(转移它的资源)
mPtr = other.mPtr;
other.mPtr = nullptr;
}
uniquePtr& operator=(uniquePtr&& other) {//移动赋值也是动资源
if (this != &other) {
//1.
//delete mPtr;
//mPtr = other.mPtr;
//other.mPtr = nullptr;
//2.
reset(other.release());
}
return *this;
}
explicit uniquePtr(pointer p = nullptr) :mPtr(p) { cout << "uniquePtr()" << endl; }
~uniquePtr() {
reset();
}
pointer release() {
pointer old = mPtr;
mPtr = nullptr;
return old;
}
pointer get()const {
return mPtr;
}
_Dx& get_deleter(){
return mDeleter;//返回删除器对象
}
const _Dx& get_deleter()const {
return mDeleter;
}
void reset(pointer p = nullptr) {
if (mPtr) {
mDeleter(mPtr);//mDeleter.operator()(this->mPtr);
}
mPtr = p;
}
void swap(uniquePtr& it) {
std::swap(it.mPtr, this->mPtr);
std::swap(it.mDeleter, this->mDeleter);
}
explicit operator bool()const {
return mPtr != nullptr;
}
_Ty* operator->()const {
return mPtr;
}
_Ty& operator*()const {
return *mPtr;
}
};
template<class _Ty, class _Dx>
class uniquePtr<_Ty[],_Dx> {
public:
using element_type = _Ty;
using pointer = _Ty*;
using deleter_type = _Dx;
private:
pointer mPtr;
deleter_type mDeleter;
public:
uniquePtr(const uniquePtr&) = delete;//unique_ptr没有拷贝构造和赋值
uniquePtr& operator=(const uniquePtr&) = delete;
uniquePtr(uniquePtr&& other) {//移动构造不要写const uniquePtr&&other,因为你要动他(转移它的资源)
mPtr = other.mPtr;
other.mPtr = nullptr;
}
uniquePtr& operator=(uniquePtr&& other) {//移动赋值也是动资源
if (this != &other) {
//1.
//delete mPtr;
//mPtr = other.mPtr;
//other.mPtr = nullptr;
//2.
reset(other.release());
}
return *this;
}
explicit uniquePtr(pointer p = nullptr) :mPtr(p) { cout << "uniquePtr()" << endl; }
~uniquePtr() {
reset();
}
pointer release() {
pointer old = mPtr;
mPtr = nullptr;
return old;
}
pointer get()const {
return mPtr;
}
_Dx& get_deleter() {
return mDeleter;//返回删除器对象
}
const _Dx& get_deleter()const {
return mDeleter;
}
void reset(pointer p = nullptr) {
if (mPtr) {
mDeleter(mPtr);//mDeleter.operator()(this->mPtr);
}
mPtr = p;
}
void swap(uniquePtr& it) {
std::swap(it.mPtr, this->mPtr);
std::swap(it.mDeleter, this->mDeleter);
}
explicit operator bool()const {
return mPtr != nullptr;
}
_Ty* operator->()const = delete;//数组不再允许使用箭头和解引用访问
_Ty& operator*()const = delete;//转而加一个[]访问
_Ty& operator[](const size_t i)const {
//此处也可以加越界检查
return mPtr[i];//return get()[i];
}
};
}
void test() {
yolo::uniquePtr<Int> ap(new Int(10));
yolo::uniquePtr<Int[]> bp(new Int[10]);
// template<class _Ty,class _Dx = my_default_deleter<_Ty> > class uniquePtr{};
// template<class _Ty, class _Dx> class uniquePtr<_Ty[],_Dx>{};
//test函数中第二行:模板参数将会匹配特化条件,编译器会优先选择特化版本。此时_Dx用泛化版本的_Dx的缺省值
//然后把“my_default_deleter<_Ty>”中的_Ty换成_Ty[]
bp[0].PrintInt();
bp[0].Value() = 90;
bp[0].PrintInt();
bp[99].PrintInt();//15110712:注意我们调用operator[]()时并没有做越界检查,没有检查size_t i的范围,
//这不是我们不想做,是无能为力做,我们可以将i<0的抛异常,
//但是i最大是多少呢?我们不知道!我们只知道我们这个智能指针管理了一组对象,这个组有多大,并不知道
}
int main() {
test();
}
unique_ptr的模拟实现
最新推荐文章于 2024-09-27 11:26:03 发布