这篇文章给大家介绍如何使用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_ptrsong2 (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++智能指针