weak_ptr<T>智能指针
weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和operator->,它的最大作用在于协助shared_ptr,像旁观者那样观测资源的使用情况。
但它有一个很大的缺点,那就是不能管理循环引用的对象。
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace std; class Parent;
class Child;
typedef boost::shared_ptr<Parent> parent_ptr;
typedef boost::shared_ptr<Child> child_ptr; class Child
{
public:
Child()
{
cout << "Child ..." << endl;
}
~Child()
{
cout << "~Child ..." << endl;
}
parent_ptr parent_;
}; class Parent
{
public:
Parent()
{
cout << "Parent ..." << endl;
}
~Parent()
{
cout << "~Parent ..." << endl;
}
child_ptr child_;
}; int main(void)
{
parent_ptr parent(new Parent);
child_ptr child(new Child);
parent->child_ = child;
child->parent_ = parent; return ;
}
amespace boost
{ template<typename T> class weak_ptr
{
public:
template <typename Y>
weak_ptr(const shared_ptr<Y> &r); weak_ptr(const weak_ptr &r); template<class Y>
weak_ptr &operator=( weak_ptr<Y> && r ); template<class Y>
weak_ptr &operator=(shared_ptr<Y> const &r); ~weak_ptr(); bool expired() const;
shared_ptr<T> lock() const;
};
}
两个常用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用智能指针。
强引用与弱引用:
强引用,只要有一个引用存在,对象就不能释放
弱引用,并不增加对象的引用计数(实际上是不增加use_count_, 会增加weak_count_);但它能知道对象是否存在
通过weak_ptr访问对象的成员的时候,要提升为shared_ptr
如果存在,提升为shared_ptr(强引用)成功
如果不存在,提升失败
对于上述的例子,只需要将Parent 类里面的成员定义改为如下,即可解决循环引用问题:
class Parent
{
public:
boost::weak_ptr<parent> child_;
};
因为此例子涉及到循环引用,而且是类成员引用着另一个类,涉及到两种智能指针,跟踪起来难度很大,我也没什么心情像分析shared_ptr 一样画多个图来解释流程,这个例子需要解释的代码远远比shared_ptr 多,这里只是解释怎样使用。
下面再举个例子说明lock() 和 expired() 函数的用法:
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
using namespace std; class X
{
public:
X()
{
cout << "X ..." << endl;
}
~X()
{
cout << "~X ..." << endl;
} void Fun()
{
cout << "Fun ..." << endl;
}
};
int main(void)
{
boost::weak_ptr<X> p;
boost::shared_ptr<X> p3;
{
boost::shared_ptr<X> p2(new X);
cout << p2.use_count() << endl;
p = p2;
cout << p2.use_count() << endl; /*boost::shared_ptr<X> */
p3 = p.lock();
cout << p3.use_count() << endl;
if (!p3)
cout << "object is destroyed" << endl;
else
p3->Fun();
}
/*boost::shared_ptr<X> p4 = p.lock();
if (!p4)
cout<<"object is destroyed"<<endl;
else
p4->Fun();*/ if (p.expired())
cout << "object is destroyed" << endl;
else
cout << "object is alived" << endl; return 0;
}
从输出可以看出,当p = p2; 时并未增加use_count_,所以p2.use_count() 还是返回1,而从p 提升为 p3,增加了use_count_, p3.use_count() 返回2;出了大括号,p2 被析构,use_count_ 减为1,程序末尾结束,p3 被析构,use_count_ 减为0,X 就被析构了。
总结:
weak_ptr是一个“弱”指针,但它能够完成一些特殊的工作,足以证明它的存在价值。
weak_ptr被设计为与shared_ptr共同工作,可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。同样,在weak_ptr析构时也不会导致引用计数的减少,它只是一个静静地观察者。
使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count() == 0,但更快,表示观测的资源(也就是shared_ptr管理的资源)已经不复存在了。
weak_ptr 没有重载operator*和->,这是特意的,因为它不共享指针,不能操作资源,这是它弱的原因。但它可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源。当expired() == true的时候,lock()函数将返回一个存储空指针的shared_ptr。
weak_ptr<T>智能指针的更多相关文章
- c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...
- c++11之智能指针
在c++98中,智能指针通过一个模板“auto_ptr”来实现,auto_ptr以对象的方式来管理堆分配的内存,在适当的时间(比如析构),释放所获得的内存.这种内存管理的方式只需要程序员将new操作返 ...
- auto_ptr,shared_ptr 智能指针的使用
Q: 那个auto_ptr是什么东东啊?为什么没有auto_array?A: 哦,auto_ptr是一个很简单的资源封装类,是在<memory>头文件中定义的.它使用“资源分配即初始化”技 ...
- c++ 智能指针、函数指针和指针函数
智能指针: 1.内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出. 2.内存溢出 out of me ...
- 智能指针 - 现代C++新特性总结
C++98中的智能指针通过一个模板类auto_ptr来实现,new操作符返回的指针可以交由它来管理,程序员不用再显式的调用delete,这在一定程度上避免了堆内存忘记释放的问题:不过auto_ptr有 ...
- [6] 智能指针boost::weak_ptr
[1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...
- C++智能指针--weak_ptr
weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...
- stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结
stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结 1. auto_ptrauto_ptr主要是用来解决资源自动释放的问题,比如如下代码:voi ...
- c++——智能指针学习(shared_ptr和weak_ptr)
先看一个例子:Stark和Targaryen家族你中有我,我中有你.我们设计以下类企图避免内存泄漏,使得析构函数都能调用到: #include<iostream> #include< ...
随机推荐
- 初心不负 笔记-JS高级程序设计-引用类型篇-Array
ES3方法集合: 1join()方法,将一个数组里面的所有元素转换成字符串,然后再将他们连接起来返回一个字符串,通过制定的符号,默认值为逗号.不会改变原数组 ,,,,]; a.join(); &quo ...
- valueof toString
valueof toString add(1)(2) // 3 add(1, 2, 3)(10) // 16 add(1)(2)(3)(4)(5) // 15 function add() { var ...
- Redis基础、应用、第三方支持组件总结
这段时间一直在研究学习Redis的相关知识,现在大概做下总结吧首先,Redis的基础方面,不说配置,就单单说下Redis数据类型:Redis 五大数据类型有String 类型,Hash 类型,List ...
- 使用Admin监控
在springboot中,也提供了很全面的监控系统.这篇文章介绍一下springboot-admin监控springboot项目. 原来大致是这样的,springboot--admin--server ...
- XamarinAndroid组件教程RecylerView动画组件使用动画(2)
XamarinAndroid组件教程RecylerView动画组件使用动画(2) 如果开发者要为RecylerView的子元素添加动画效果,需要使用RecyclerView类中的SetItemAnim ...
- [CF528D]Fuzzy Seach
Description: 有两个基因串S和T,他们只包含AGCT四种字符.现在你要找出T在S中出现了几次. 有一个门限值k≥0.T在S的第i(1≤i≤|S|-|T|+1)个位置中出现的条件如下:把T的 ...
- 狡猾的商人 [HNOI2005] [一题双解]
Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...
- 2017.07.14【NOIP提高组】模拟赛B组
Summary 这次比赛因为迟到了,少了很多时间,也受到了相应的惩罚,这是好的,是个标记牌,警醒着我.这次比赛的题目很难,也就是说,大家的得分都很低,总的来说,收获还是很大的,因为有非常多的技巧被掌握 ...
- Yii2 数组助手类arrayHelper
数组助手类 ArrayHelper 1.什么是数组助手类 Yii 数组助手类提供了额外的静态方法,让你更高效的处理数组. a.获取值(getValue) class User { public $na ...
- Yii2 baisic版gii的使用和分页
一.Gii 的使用 1.配置 gii 的位置: 在 config/web.php 里面: if (YII_ENV_DEV) { $config['bootstrap'][] = 'gii'; $con ...