C++内存管理——unique_ptr

1. 概述

本想将unique_ptr, shared_ptr和weak_ptr写在同一篇文章中,无奈越(废)写(话)越(连)长(篇),本着不给自己和读者太大压力的原则,最终决定分为三篇去描述它们(不是恶意凑文章数哦)。
本篇文章主要描述了unique_ptr,在此之前先给出了auto_ptr的介绍,废话不说,直入正题。

2. auto_ptr

auto_ptr是在C++ 98中引入的,在C++ 17中被移除掉。它的引入是为了管理动态分配的内存,它的移除是因为本身有严重的缺陷,并且已经有了很好的替代者(unique_ptr)。
auto_ptr采用"Copy"语义,期望实现"Move"语义,有诸多的问题。标准库中的auto_ptr和《Move语义和Smart Pointers先导(以一个例子说明)》中的AutoPtr2十分类似,此处再次给出代码并分析它的问题。

template
struct AutoPtr2
{
    AutoPtr2(T* ptr = nullptr)
        : ptr(ptr)
    {
    }

    ~AutoPtr2()
    {
        if(this->ptr != nullptr)
        {
            delete this->ptr;
            this->ptr = nullptr;
        }
    }

    AutoPtr2(AutoPtr2& ptr2) // not const
    {
        this->ptr = ptr2.ptr;
        ptr2.ptr = nullptr;
    }

    AutoPtr2& operator=(AutoPtr2& ptr2) // not const
    {
        if(this == &ptr2)
        {
            return *this;
        }

        delete this->ptr;
        this->ptr = ptr2.ptr;
        ptr2.ptr = nullptr;
        return *this;
    }

    T& operator*() const
    {
        return *this->ptr;
    }

    T* operator->() const
    {
        return this->ptr;
    }

    bool isNull() const
    {
        return this->ptr == nullptr;
    }

private:
    T* ptr;
};

以上采用"Copy"语义,期望实现"Move"语义的实现有以下三大问题:

  1. auto_ptr采用拷贝构造和拷贝赋值构造去实现"Move"语义,若将auto_ptr采用值传递作为函数的参数,当函数执行结束时会导致资源被释放,若之后的代码再次访问此auto_ptr则会是nullptr;
  2. 由于auto_ptr总是使用"non-array delete",所以它不能用于管理array类的动态内存;
  3. auto_ptr不能和STL容器和算法配合工作,因为STL中的"Copy"真的是"Copy",而不是"Move"。

由于auto_ptr有诸多问题,需要一个更加完美的"Smart Point",unique_ptr也就应运而生了。

3. unqiue_ptr

3.1 Smart Points简介

Smart Points是什么,或者说它是用来干什么的?它是用来管理动态分配的内存的,它能够动态地分配资源且能够在适当的时候释放掉曾经动态分配的内存。
此时对智能指针来说就有两条原则:

  1. 智能指针本身不能是动态分配的,否则它自身有不被释放的风险,进而可能导致它所管理对象不能正确地被释放;
  2. 在栈上分配智能指针,让它指向堆上动态分配的对象,这样就能保证智能指针所管理的对象能够合理地被释放。

3.2 unique_ptr的实现

unique_ptr是独占式的,即完全拥有它所管理对象

你可能感兴趣的:(c++,c++11)