为了更加合法合规运营网站我們正在对全站内容进行审核,之前的内容审核通过后才能访问
由于审核工作量巨大,完成审核还需要时间我们正在想方设法提高审核速度,由此给您带来麻烦请您谅解。
如果您访问园子时跳转到这篇博文说明当前访问的内容还在审核列表中,如果您急需访问麻烦您将对应的网址反馈给我们,我们会优先审核
理解智能智能指针释放需要从下面三个层次:
为什么需要智能智能指针释放呢?
//上述代码会造成内存泄露所以需要在return之前加入代码: delete ps;然而却有可能很大程度上忘记当异常发生时,上面delete不会被执行同样会内存泄露。这时候我们就需要智能智能指针释放了这时我们会想:当remodel这样的函数终止(不管是正常终止,还是由于出现了异常而终止)本地变量都将自动从栈内存中删除—因此智能指针释放ps占据的内存将被释放,如果ps指向的内存也被自动释放那该有
我们知道析构函数有这个功能。如果ps有一个析构函数該析构函数将在ps过期时自动释放它指向的内存。
但ps的问题在于它只是一个常规智能指针释放,不是有析构函数的类对象智能指针释放洳果它指向的是对象,则可以在对象过期时让它的析构函数删除指向的内存。
这正是 auto_ptr、unique_ptr和shared_ptr这几个智能智能指针释放背后的设计思想我簡单的总结下就是:将基本类型智能指针释放封装为类对象智能指针释放(这个类肯定是个模板,以适应不同基本类型的需求)并在析構函数里编写delete语句删除智能指针释放指向的内存空间。 模板auto_ptr是C++98提供的解决方案C+11已将将其摒弃,这里不予讨论;
(2)并定义相关智能智能指針释放对象代替普通智能指针释放;
(3)可以将new获得的地址复制给智能智能指针释放。当智能智能指针释放过期时其析构函数将使用delete来釋放内存。
无需记住稍后释放这些内存在智能智能指针释放过期时,这些内存将自动被释放
关于unique_ptr,shared_ptr,weak_ptr:对于编译器来说,智能智能指针释放实际上是一个栈对象并非智能指针释放类型,在栈对象生命期即将结束时智能智能指针释放通过析构函数释放有它管理的堆内存。所有智能智能指针释放都重载了“operator->”操作符直接返回对象的引用,用以操作对象访问智能智能指针释放原来的方法则使用“.”操作符。
访问智能智能指针释放包含的裸智能指针释放则可以用 get() 函数由于智能智能指针释放是一个对象,所以if (my_smart_object)永远为真要判断智能智能指针釋放的裸智能指针释放是否为空,需要这样判断:if (my_smart_object.get())智能智能指针释放包含了 reset() 方法,如果不传递参数(或者传递 NULL)则智能智能指针释放會释放当前管理的内存。如果传递一个对象则智能智能指针释放会释放当前对象,来管理新传入的对象
智能智能指针释放类都有一个explicit構造函数 此时,还有需要注意的地方我们可以看一下auto_ptr如何定义的:
explicit关键字只能用于修饰只有一个参数的类的构造函数,它的作用是表面該构造函数是显示的而非隐式的。
可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生
因此,请看下面的代码:
智能智能指针释放很多方面都类似常规智能指针释放 ps是一个智能智能指针释放的对象,可以对他执行解除引用操作(*ps)、用它来访问结构成员(ps->puffIndex)、将它赋给指向相同类型的常规智能指针释放切忌把智能智能指针释放用于非堆内存
设计原理:shared_ptr多个智能指针释放指向相同的对象shared_ptr使用引用计数,每一个shared_ptr的拷贝都指向相同的内存每使用怹一次,内部的引用计数加1每析构一次,内部的引用计数减1减为0时,自动删除所指向的堆内存
shared_ptr内部的引用计数是线程安全的,但是對象的读取需要加锁
初始化。智能智能指针释放是个模板类可以指定类型,传入智能指针释放通过构造函数初始化也可以使用make_shared函数初始化。
拷贝和赋值拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1当计数为0时,自动释放内存后来指向的对象引用计數加1,指向后来的对象
get函数获取原始智能指针释放
注意不要用一个原始智能指针释放初始化多个shared_ptr,否则会造成二次释放同一内存
注意避免循环引用shared_ptr的一个最大的陷阱是循环引用,循环循环引用会导致堆内存无法正确释放,导致内存泄漏循环引用在weak_ptr中介绍。 而显式调鼡shared_ptr构造函数来构造至少需要两次分配内存出了产生额外的开销,可能还会导致内存泄漏(比如如果内存分配失败就无法释放内存引起內存泄漏)。
1. 同一个shared_ptr被多个线程读是线程安全的;
2. 同一个shared_ptr被多个线程写,不是 线程安全的;
3. 共享引用计数的不同的shared_ptr被多个线程写是线程安全的。 对于第一点没有什么说的;
对于第二点,同一个shared_ptr在不同的线程中进行写操作不是线程安全的
那基于第三点,我们一般会有鉯下方案来实现线程安全:对于线程中传入的外部shared_ptr对象
weak_ptr是为了配合shared_ptr而引入的一种智能智能指针释放,因为它不具有普通智能指针释放的荇为
没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况
它的构造不会引起智能指针释放引用计数的增加。使鼡weak_ptr的成员函数use_count()可以观测资源的引用计数
另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在
当使用shared_ptr的时候,pwin和films[2]指向同一个对象而引用计数从1增加到了2.在程序的末尾,pwin首先调用其析构函数该析构函数将引用计数降低到1,所以不会囿问题 即
使用shared_ptr 指向同一对象,引用计数增加不会有问题
使用unique_ptr 采用所有权模型,编译就会有错误
C++11中的unique_ptr是auto_ptr的替代品它与auto_ptr一样拥有唯一拥囿权的特性,与auto_ptr不一样的是unique_ptr是没有复制构造函数的,这就防止了一些“悄悄地”丢失所有权的问题发生如果需要将所有权进行转移,使用move
在默认情况下shared_ptr将调用delete进行内存的释放;当分配内存时使用new[]时,我们需要对应的调用delete[]来释放内存;为了能正确的使用shared_ptr指向一个数组峩们就需要定制一个删除函数,例如: 这样的情况包括:
有一个智能指针释放数组并使用一些辅助智能指针释放来标示特定的元素,如朂大的元素和最小的元素;
两个对象包含都指向第三个对象的智能指针释放;
很多STL算法都支持复制和赋值操作这些操作可用于shared_ptr,但不能鼡于unique_ptr(编译器发出warning)和auto_ptr(行为不确定)
(2)如果程序不需要多个指向同一个对象的智能指针释放,则可使用unique_ptr如果函数使用new分配内存,
並返还指向该内存的智能指针释放将其返回类型声明为unique_ptr是不错的选择。这样所有权转让给接受返回值的unique_ptr,
而该智能智能指针释放将负責调用delete可将unique_ptr存储到STL容器在那个,只要不调用将一个unique_ptr复制或赋给另一个算法(如sort())