到C++11中的智能指针
来源:互联网 发布:移动办公软件有哪些 编辑:程序博客网 时间:2024/06/05 07:50
本章写的很好,先后顺序,递进关系写的非常好,code简洁说明问题.在论述weak_ptr,不是直接论述weak_ptr解决死锁,先介绍weak_ptr基本用法,然后在说解决死锁.
notes: unique ptr 是唯一。不能赋值,拷贝。 share_ptr引用计数。weak_ptr防止share_ptr死锁,不增加引用计数。其又不同于普通指针,可以自动析构.
http://www.jellythink.com/archives/684
到C++11中的智能指针
千呼万唤始出来
上一篇《从auto_ptr说起》中详细的总结了C++98标准中的auto_ptr
,但是随着C++11的到来,auto_ptr
已经不再了,即将成为历史;好的东西总是会受到大家的欢迎的,随着大家都在使用“准”标准库boost中的shared_ptr
;C++标准委员会终于觉的是时候将shared_ptr
加入到C++11中去了。欢呼声一片,至少我是这么觉的了;至少shared_ptr
让我用起来,还是不错的。接下来,就总结一下C++11中的这些智能指针吧。
C++11有哪些智能指针
先来一段简单的代码,看看C++11中到底有哪些智能指针。
C++11中主要提供了unique_ptr
、shared_ptr
和weak_ptr
这三个智能指针来自动回收堆分配的对象。看看上面的代码,感觉用起来也还挺轻松的,也还不错,至少是比auto_ptr
好点。
unique_ptr
C++11中的unique_ptr
是auto_ptr
的替代品,它与auto_ptr
一样拥有唯一拥有权的特性,与auto_ptr
不一样的是,unique_ptr
是没有复制构造函数的,这就防止了一些“悄悄地”丢失所有权的问题发生,如果需要将所有权进行转移,可以这样操作:
只有在使用者显示的调用std::move
之后,才会发生所有权的转移,这样就让使用者知道自己在干什么。再来一段代码,看看将unique_ptr
作为函数参数和返回值的使用情况:
由于在unique_ptr
中是没有复制构造函数的,所以在直接传参时,进行值传递时,建立临时变量时,就会出错了,所以需要显示的调用move
,转移所有权;而函数的返回值已经进行了move
操作,而不用显示的进行调用。
shared_ptr
在最开始的那段代码中,也简单的使用了一下shared_ptr
。shared_ptr
名如其名,它允许多个该智能指针共享地“拥有”同一堆分配对象的内存;由于它的资源是可以共用的,所以也就可以透过operator=
等方法,来分享shared_ptr
所使用的资源。由于shared_ptr
内部实现上使用的是引用计数这种方法,所以一旦一个shared_ptr
指针放弃了“所有权”,其它的shared_ptr
对对象的引用并不会发生变化;只有在引用计数归零的时候,shared_ptr
才会真正的释放所占有的堆内存空间的。对于引用计数的问题,我这里就不再多总结了,可以参考以下文章:
– 智能指针-引用计数实现
– COM中的引用计数1
– COM中的引用计数2
我这里注重的总结shared_ptr
的使用,并不会对shared_ptr
进行源码级别的分析。再来一段简单的代码,看看shared_ptr
的一些应用。
自己单独想想程序的输出。输出如下:
shared_ptr指向数组
在默认情况下,shared_ptr
将调用delete
进行内存的释放;当分配内存时使用new[]
时,我们需要对应的调用delete[]
来释放内存;为了能正确的使用shared_ptr
指向一个数组,我们就需要定制一个删除函数,例如:
上面的代码看不懂的,请参考这篇《C++中的Lambda表达式》文章。如果确实需要共享地托管一个对象,使用unique_ptr
也许会更简单一些,比如:
线程安全
关于多线程中使用shared_ptr
,有如下几点描述:
1. 同一个shared_ptr
被多个线程读,是线程安全的;
2. 同一个shared_ptr
被多个线程写,不是 线程安全的;
3. 共享引用计数的不同的shared_ptr
被多个线程写,是线程安全的。 对于第一点,没有什么说的;对于第二点,同一个shared_ptr
在不同的线程中进行写操作不是线程安全的,那基于第三点,我们一般会有以下方案来实现线程安全:
对于线程中传入的外部
shared_ptr
对象,在线程内部进行一次新的构造,例如: sharedptr AObjTmp = outerSharedptrObj;
环形引用
对于使用引用计数实现的智能指针,总是避免不了这个问题的。如果出现类似下面的代码,那就出现了环形引用的问题了。
要解决环形引用的问题,没有特别好的办法,一般都是在可能出现环形引用的地方使用weak_ptr
来代替shared_ptr
。说到了weak_ptr
,那下面就接着总结weak_ptr
吧。
weak_ptr
weak_ptr
是最麻烦的,也比较拗口的;它可以指向shared_ptr
指针指向的对象内存,却并不拥有该内存。但是,使用weak_ptr
成员lock
,则可返回其指向内存的一个shared_ptr
对象,且在所指对象内存已经无效时,返回指针空值(nullptr)。由于weak_ptr
是指向shared_ptr
所指向的内存的,所以,weak_ptr
并不能独立存在。例如以下代码:
所以,我们在使用weak_ptr
时也要当心,时刻需要判断对应的shared_ptr
是否还有效。对于上面的环形引用的问题,由于weak_ptr
并不会增加shared_ptr
的引用计数,所以我们就可以使用weak_ptr
来解决这个问题。
总结
这篇文章有点长,但是很详细的总结了C++11中的智能指针相关的问题,希望这篇文章对大家有用。
- C ++中的智能指针
- 到C++11中的智能指针
- 到C++11中的智能指针
- c++ 11 中的智能指针
- C++11中的智能指针
- c++11中的智能指针
- C++11中的智能指针
- C++11中的智能指针
- C++11中的智能指针
- c++11中的智能指针
- C/C++: stl 和 boost 中的智能指针
- Boost中的智能指针
- Nebula中的智能指针
- Qt中的智能指针
- Boost 中的智能指针
- WebKit中的智能指针
- WebKit中的智能指针
- C++中的智能指针
- js, jq执行 focus后focusout和click事件冲突
- 循环从键盘输入
- iOS探索--面向对象三大特征封装、继承、多态
- [js]js中函数的执行过程图解
- Read semi-sync reply magic number error
- 到C++11中的智能指针
- Vijos[1983]NOIP2015Day2T3 运输计划 transport LCA
- perl笔记(三)-正则表达式
- Redis指令简单操作
- HDU 6105 Gameia(2017多校第6场1010)
- 16 个 Linux 服务器监控命令和watch
- Java+opencv3.2.0之图像尺寸调整
- itk中的图像分割算法(二)
- POJ