C++11智能指针之weak_ptr
来源:互联网 发布:excel数据递增 编辑:程序博客网 时间:2024/06/07 03:03
weak_ptr是一种弱智能指针,它具有类似shared_ptr的行为,但是却不会影响的它所指向的资源的引用计数。Weak_ptr不能被解引用,也不能被测试是否为null。
weak_ptr之所以具备这些特点,是因为weak_ptr不是一个独立的指针,而是shared_ptr的一个附加物。Weak_ptr是通过shared_ptr创建出来的,正像如下代码:
auto spw =std::make_shared<Investment>();
std::weak_ptr<Investment>wpw(spw);
如果此时,将spw赋值为null,spw所管理的资源会被析构,那么wpw也就成为了悬空指针,也称为“过期”(expired),可以通过expired()判断weak_ptr是否过期。
spw =nullptr;
if (!wpw.expired()) {}
在使用weak_ptr时,我们通常会考虑先用expired()判断其是否过期,如果没有过期,就通过它来访问所管理的资源,但是我们在一开头的时候说过,weak_ptr不能被解引用,所以,自然我们也不可能用它来访问它所指向的资源,即便weak_ptr可以被解引用,这么做也是不安全的,因为判断是否过期和解引用是两个独立的动作,在多线程环境下,会出现线程竞争,所以这不是一种线程安全的做法。
正确的做法是,当我们想要访问weak_ptr所指向的资源时,应当将weak_ptr转为一个shared_ptr,通过shared_ptr来访问资源。这里有两种方法来做这件事:
1通过weak_ptr的lock()调用
std::shared_ptr<Investment>spw1 = wpw.lock();//如果wpw过期,则返回null
2将weak_ptr作为shared_ptr构造函数的参数
std::shared_ptr<Investment>spw2(wpw);
那么,既然weak_ptr无法被解引用,那它到底有什么用处呢?
weak_ptr的用处主要体现在两方面:
需要获知所管理的资源是否过期
设想在观察者模式中,最重要的两个角色是主体和观察者,主体中拥有某种资源,并且维护了一个观察者列表,当主体拥有的某种资源的状态发生变化时,主体就会通知观察者列表中的观察者,观察者得到这个通知后,会针对这个变化进行相应的操作。
在观察者模式中,主体无法主宰观察者列表中的观察者的生命周期,它只需要知道,在列表中的这些观察者是否“健在”就可以了,所以,我们可以用一个元素类型为weak_ptr的列表来存放主体所拥有的观察者了。
2. 解决shared_ptr的循环引用问题shared_ptr的循环引用是指两个对象中都有一个shared_ptr指向另一个对象的情况,如图所示:
如果A要析构的话,就会首先尝试去销毁它所管理的资源,即销毁B,但是B中也有一个shared_ptr指向了A,B要析构,也会去尝试首先销毁它所拥有的资源,即销毁A,这样的话,就会出现无限循环,两个对象都无法被销毁,从而造成内存泄漏。
解决循环引用的办法就是,使用weak_ptr,如图所示,在B中使用weak_ptr指向A,这时候就不会出现循环引用的问题了
- C++11智能指针之shared_ptr、weak_ptr
- C++11智能指针之shared_ptr、weak_ptr
- C++11智能指针之weak_ptr
- c++11:智能指针之weak_ptr
- 智能指针之boost::weak_ptr
- 【C++11新特性】 C++11智能指针之weak_ptr
- 【C++11新特性】 C++11智能指针之weak_ptr
- 【C++11新特性】 C++11智能指针之weak_ptr
- C++11新特性之智能指针(shared_ptr/unique_ptr/weak_ptr)
- 【C++】智能指针auto_ptr/unique_ptr/shared_ptr/weak_ptr!!!
- boost智能指针之shared_ptr和weak_ptr
- 智能指针(五)之weak_ptr
- c++智能指针(五)之weak_ptr
- C++11 智能指针 unique_ptr shared_ptr weak_ptr
- C++11智能指针——weak_ptr
- 智能指针weak_ptr
- 智能指针 weak_ptr
- 智能指针--shared_ptr&&weak_ptr
- 机器人的运动范围dfs
- Story 32-33
- (搬运).net起步 (自定义 ASP.NET CreateUserWizard 控件1)
- 使用hexo+GitHub搭建自己的博客中遇到问题的解决方法及博客美化
- system("pause")
- C++11智能指针之weak_ptr
- 空间配置器
- Qt之QLineEdit
- Python的坑(7) -- 定义默认参数要牢记一点:默认参数必须指向不变对象!
- web开发第二天
- The Boost Graph Library(1)
- Netty5入门学习笔记004-使用Netty传输POJO对象
- 组装原有控件实现横向滚动的时间选择器,可滑动 点击,初始状态在指定位置
- 设计模式-单例模式之饿汉式-多线程