C++智能指针详解之unique_ptr

概述

        智能指针可以帮助管理动态分配的内存,是避免内存泄漏的有用技术。智能指针可用于管理在函数作用域内(或作为类的数据成员)动态分配的资源,当智能指针离开作用域或者被重置时,会自动释放所占用的资源。

        智能指针有多种类型。最简单的智能指针类型std::unique_ptr对资源有唯一的所有权,稍微高级点的智能指针允许共享所有权,即多个智能指针指向同一个资源,当这样的智能指针离开作用域或者被重置时,仅当它是指向该资源的最后一个智能指针时,才会释放指向的资源,标准库提供了std::shared_ptr,它支持共享所有权。

        应将unique_ptr用作默认智能指针,仅当需要共享资源时,才使用shared_ptr。使用智能指针需添加头文件

unique_ptr

        unique_ptr拥有唯一的所有权,当unique_ptr被销毁或重置时,自动释放资源。它的一个优点是,内存和资源总会被释放,即使在执行return语句或抛出异常时也是如此。例如,当函数有多个return语句时,不必在每个return语句之前都写一个释放资源的动作,简化了编码过程。

1. 创建unique_ptr

        参考下面的函数,在自由存储区上分配了一个Simple对象,并且有调用delete,你可能认为代码正确地释放了内存,但这个例子仍然可能会产生内存泄漏!如果go()方法抛出异常,将永远不会调用delete,导致内存泄漏。

void func(){
    Simple* mySimplePtr = new Simple();
    mySimplePtr->go();
    delete mySimplePtr;
}

        下面的函数使用了unique_ptr,Simple对象不会显式地释放,但unique_ptr实例在离开作用域或遇到异常时,就会在其析构函数种自动释放Simple对象。unique_ptr通过std::make_unique()辅助函数创建。

void func(){
    auto mySmartPtr = make_unique();
    mySmartPtr->go();
}

2. 使用unique_ptr

        像标准指针一样,仍可以使用*或者->对智能指针进行解引用。

mySmartPtr->go();
(*mySmartPtr).go();

        get()方法,可用于直接获得底层指针。可将指针传递给需要普通指针的函数。

void func(Simple* simple){
    ...
}
// 可采用如下方式调用
func(mySmartPtr.get())

        reset()方法,可释放unique_ptr的底层指针,并根据需要改成另一个指针。

mySmartPtr.reset();  // 释放资源并且指向nullptr
mySmartPtr.reset(new Simple());  // 释放资源并且指向一个新的Simple实例

        release()方法,断开unique_ptr与底层指针的连接。它返回底层指针,并将智能指针设置为nullptr,则智能指针失去了对资源的所有权,需要在使用完资源时手动释放。

Simple* simple = mySmartPtr.release();  // 释放智能指针对资源的所有权
	...
delete simple;  // 手动释放
simple = nullptr;

        由于unique_ptr代表唯一拥有权,因此无法复制它!但是可以用移动语义将一个unique_ptr移动到另一个,std::move()函数可以显式移动unique_ptr所有权。          

你可能感兴趣的:(C++,c++,开发语言,c语言,visualstudio,后端)