一.unique_ptr的介绍
在C++中,为了防止内存泄漏和野指针的产生,创建了智能指针,而unique_ptr便是其中一种,这个产物本质上就是让指针可以像对象一样使用,而这个指针的缺点就是只能够指向同一个空间一次,而不可以重复指向同一个空间,原因就是防止析构时发生混乱和错误
二.unique_ptr的实现
在对这个指针的介绍中,我们知道所谓的智能指针只是将指针封装为一个对象,所以说在智能指针的成员中肯定有指针的变量,而且我们知道对于这个智能指针来说,其他的变量也暂时不需啊,并且肯定要满足所有类型的指针,因此要采用模版。
template<typename T>
class unique_ptr
{
private: T* ptr;
这便是智能指针的成员变量,有了成员变量以后,就要考虑构造函数和析构函数了,在智能指针中,构造函数肯定是将智能指针指向对应的空间或者产生一个不指向任何空间的智能指针,因此一个基础的构造函数就产生了、
unique_ptr(T*p = nullptr)
:ptr(p)
{}
但是我们要知道这个智能指针(unique_ptr)是不能够指向同一块空间两次的,所以不能有拷贝构造函数和拷贝函数,除非是移动拷贝和移动拷贝构造。
unique_ptr(unique_ptr& p) = delete;
unique_ptr operator = (unique_ptr& p) = delete;
然后便是对移动拷贝构造函数和移动拷贝函数的实现了,首先是实现移动拷贝构造函数,因为移动拷贝构造函数实现了以后,原本的那个智能指针也就消失了,所以我们肯定要先将指针指向对应的空间,然后将原本的指针指向nullptr,也就结束了。
unique_ptr(unique_ptr&& p)
:ptr(p.ptr)
{
p.ptr = nullptr;
}
下面就是移动拷贝函数了,首先判断自己空间的内容是否和拷贝的空间一至,如果一至,则直接返回,如果不一致,则进行对自己指向空间的析构,然后将对方的指针进行拷贝,将对方指针进行指向nullptr。然后返回自己
unique_ptr operator = (unique_ptr&& p)
{
if (this != &p)
{
delete this.ptr;
this->ptr = p.ptr;
p.ptr = nullptr;
}
return *this;
}
然后是析构函数,对于析构函数而言,肯定是要将现在的智能指针指向的空间给释放掉,因此
~unique_ptr()
{
delete ptr;
}
下面是两个运算符的重载,使得这个对象使用起来像是和指针一样,那便是*和->,对于*,我们只需要将这个智能指针的*ptr进行返回就行,对于->而言,我们只需要将ptr本身返回就行
T operator *()
{
return *ptr;
}
T* operator ->()
{
return ptr;
}
剩下就是一些非常简单的函数了
T* get() const { return ptr; }
// 判断是否为空
bool operator!() const { return ptr == nullptr; }
bool operator==(std::nullptr_t) const { return ptr == nullptr; }
bool operator!=(std::nullptr_t) const { return ptr != nullptr; }