如何使用c++智能指针

  介绍

这篇文章给大家介绍如何使用c++智能指针,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

简介

在现代c++编程中,标准库包含了智能指针(智能指针)。

智能指针用来确保程序不会出现内存和资源的泄漏,并且是“异常安全“异常安全的。

智能指针的使用

智能指针定义在头文件记忆里的命名空间性病中。它对于资源获取即初始化(RAII,资源获取初始化)编程理念至关重要。该理念的目的是保证对象初始化的时候也是资源获取的时候,从而使对象的所有资源在单行代码中创建。

实践中,RAII的主要原则就是把任何在堆上分配的资源(比如动态分配的内存或者系统对象的处理)的所有权提供给在栈上分配的对象(其析构函数包含释放资源及相关清理的代码)。

大多数时候,当你初始化一个原始指针或者资源句柄使其指向实际的资源时,立即将其传给智能指针。

在现代c++中,原始指针只用于包含在局部作用域,循环或者工具函数的小块代码中(对性能有要求,并且对资源的所有权也不容易混淆)。

原始指针和智能指针的声明比较如下:

void  UseRawPointer ()   {   ,//Using  a  raw  pointer ——not 建议。   ,歌曲* pSong =, new 歌(L" Nothing 提醒你。,,L" Bruno  Mars"),,      ,//Use  pSong…      ,//不要# 39;t  forget 用删除!   ,delete  pSong;   }      void  UseSmartPointer ()   {   ,//Declare  a  smart  pointer 提醒stack 以及pass  it 从而raw 指针。   ,unique_ptr song2 (new 歌曲(L" Nothing 提醒你。,,L" Bruno  Mars"));      ,//Use  song2…   ,wstring  s =, song2→duration_;   ,//?      },//,song2  is  deleted  automatically 这里。

如上所示,智能指针是一个在栈上声明的类模板,并由指向分配在堆上的对象的原始指针初始化。当智能指针初始化后,它就拥有了原始指针的所有权。这意味着智能指针需要负责原始指针指向的内存释放。智能指针的析构函数包含了删除的调用,并且由于智能指针是在栈上声明的,其析构函数会在智能指针对象离开作用域时被调用,即使在栈中发生了异常。

通过使用指针运算符(→和*)访问被封装的指针,智能指针类重载了这些运算符以返回被封装的原始指针。

c++智能指针的理念类似于在c#语言中创建对象的过程:创建对象后让系统负责在正确的时间将其删除。不同之处在于,没有独立的垃圾回收器运行于后台;内存是按照标准c++规范对内存进行管理的,使运行时环境更加快速和高效。

[!重要]

总是在单独的行上创建智能指针,而不是在参数列表中,从而避免由于特定的参数列表分配规则出现一些轻微的内存泄漏

以下示例显示了c++标准库中的unique_ptr是如何封装指向大型对象的指针的。

class  LargeObject   {   公众:   ,void  DoSomething () {}   };      void  ProcessLargeObject (const  LargeObject&, lo) {}      void  SmartPointerDemo ()   {,   ,//Create 从而object 以及pass  it 用a  smart 指针   ,std:: unique_ptr

上述示例演示了使用智能指针的关键步骤:

<李>

将智能指针声明为局部变量(不要在智能指针上使用新的或者malloc表达式)。

<李>

在类型参数上,指定被封装指针指向的对象类型。

<李>

将指向由新的创建的对象的指针传给智能指针的构造函数。

<李>

使用重载的操作符→和*来访问对象。

<李>

让智能指针来删除对象。

智能指针在设计上兼顾了内存和性能的高效性,例如,unique_ptr唯一的数据成员是被封装的原始指针,这意味着unique_ptr具有原始指针同样地大小,4字节或者8字节。通过智能指针重载的操作符→和*来访问并不比直接使用原始指针来访问慢多少。

如何使用c++智能指针