1.唯一性智能指针的删除器
class Object
{
public:
Object() {
}
Object() = default;//告诉编译器产生一个默认的构造函数
};
//泛化版本,接收一个数据
template<class _Ty>
class MyDeletor
{
public:
MyDeletor() = default;//默认构造函数
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;
}
}
};
int main()
{
MyDeletor<Object> op;
MyDeletor<Object[]> arop;
Object* p = new Object(10);//创建一个对象
op(p);//调用的是泛化版本
p = new Object[10];//创建一组对象
arop(p);//调用的是特化版本
return 0;
}
2.画出下面函数的内存分布图
class Object
{
public:
Object() {
}
Object() = default;//告诉编译器产生一个默认的构造函数
};
//泛化版本,接收一个数据
template<class _Ty>
class MyDeletor
{
public:
MyDeletor() = default;//默认构造函数
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 _Dx = MyDeletor<_Ty>>
class my_unique_ptr
{
public:
//C11标准可以用using进行重定义,和typedef的作用是一样的,两者是等价的
using pointer = _Ty*; //typedef _Ty* pointer
using element_type = _Ty;//typedef _Ty element_type
using delete_type = _Dx; //typedef _Dx delete_type
private:
_Ty* _Ptr;
_Dx _myDeletor;
public:
my_unique_ptr(pointer _P = nullptr) :_Ptr(_P) {
}
~my_unique_ptr()
{
if (_Ptr != nullptr)
{
_myDeletor(_Ptr);
_Ptr = nullptr;
}
}
my_unique_ptr(my_unique_ptr&& _Y)
{
_Ptr = _Y._Ptr;
_Y._Ptr = nullptr;
}
my_unique_ptr& operator=(my_unique_ptr&& _Y)
{
if(this == &_Y)
return *this;
}
};
int main()
{
my_unique_ptr<Object> op(new Object(10));
return 0;
}
op在析构的时候调用~my_unique_ptr()函数,_myDeletor是一个对象,对象加()调用的是对象的仿函数(operator()函数)
如果将拷贝构造函数和赋值函数删除掉,将无法使用拷贝构造函数和赋值函数
my_unique_ptr(cosnt my_unique_ptr&) = delete;//删除拷贝构造函数
my_unique_ptr& operator=(cosnt my_unique_ptr&) = delete;//删除赋值函数
int main()
{
my_unique_ptr<Object> op1(new Object(10));//和下面是等价的
//my_unique_ptr<Object> op2 = make_unique<Object>(10);//两者是等价的
my_unique_ptr<Object> op2(op1);//error,无法使用拷贝构造函数
my_unique_ptr<Object> op3;
op3 = op1;//error,无法使用赋值函数
return 0;
}
在上面代码的基础上,下面funa和funb函数哪个不能编译通过?
my_unique_ptr<Object> funa()
{
my_unique_ptr<Object> op(new Object(10));
return op;
}
my_unique_ptr<Object> funb()
{
return my_unique_ptr<Object>(new Object(10));
}
答案:funa不能通过,op是一个有名对象,返回的时候要构建临时对象,会调用拷贝构造函数,但是拷贝构造函数已经被删掉了,所以不能编译通过,funb返回的是一个无名对象,无名对象是一个右值对象,调用的是右值构造(移动构造),所以funb可以编译通过
3.唯一性智能指针的所有代码(处理的是单个对象)
class Object
{
public:
Object() {
}
Object() = default;//告诉编译器产生一个默认的构造函数
};
//泛化版本,接收一个数据
template<class _Ty>
class MyDeletor
{
public:
MyDeletor() = default;//默认构造函数
void operator()(_Ty* ptr) const
{
if (ptr != nullptr)
{