小言_互联网的博客

C++ Boost库:弱引用智能指针 weak_ptr

254人阅读  评论(0)

C++ Boost库:简介和第一个示例程序
C++ Boost库:数值转换 lexical_cast
C++ Boost库:字符串格式化 format
C++ Boost库:字符串string_algo
C++ Boost库:字符串算法string_algo
C++ Boost库:类型推导BOOST_AUTO/BOOST_TYPEOF
C++ Boost库:分词处理库 tokenizer
C++ Boost库:windows下编译Boost库
C++ Boost库:日期时间库 date_time
C++ Boost库:智能指针scoped_ptr
C++ Boost库:数组智能指针 scoped_array
C++ Boost库:共享所有权的智能指针 shared_ptr
C++ Boost库:工厂函数 make_shared
C++ Boost库:共享有权的数组智能指针shared_array
C++ Boost库:弱引用智能指针 weak_ptr
C++ Boost库:禁止拷贝 nocopyable
C++ Boost库:计时器 timer
C++ Boost库:普通数组array
C++ Boost库:散列容器 unordered_set、unordered_multiset
C++ Boost库:散列容器 unordered_map、unordered_multimap
C++ Boost库:双向映射容器 bimap
C++ Boost库:环形缓冲区 circular_buffer
C++ Boost库:动态多维数组 multi_array
C++ Boost库:使用property_tree解析XML和JSON
C++ Boost库:简化循环 BOOST_FOREACH
C++ Boost库:随机数库 Random
C++ Boost库:引用库 ref
C++ Boost库:绑定库 bind
C++ Boost库:线程库 thread 跨平台多线程
C++ Boost库:互斥量 mutex

1. 简介

weak_ptr设计的目的是为了来协助 shared_ptr工作,它只可以从一个 shared_ptr或另一个 weak_ptr对象构造,它的构造和析构不起引用记数的增加或减少,使用需要包含头文件:

#include<boost/weak_ptr.hpp>

注:C++11标准中的 std::weak_ptrboost::weak_ptr 功能相似。

shared_ptr构造或析构导致引用计数加减1,而weak_ptr不会引起引用计数的改变。

shared_ptrweak_ptr的区别:

区别 weak_ptr shared_ptr
构造 weak_ptrshared_ptr构造 newshared_ptr构造
指针功能 不支持*->操作符重载 支持*->操作符重载
引用计数改变 不影响对应的shared_ptr内部计数 改变引用计数
成员函数 use_count 返回引用计数
expired 检测所管理的对象是否释放
resetweak_ptr置空
swap 交换两个shared_ptr对象
lock 创建新的shared_ptr对象并使计数+1
use_count 返回引用计数
unique 返回是否独占所有权
reset 放弃所有权并使计数-1
swap 交换两个shared_ptr对象
get 返回内部对象(指针)

2. 使用示例

#include<iostream>
using namespace std;   

#include<boost/weak_ptr.hpp>
#include<boost/shared_ptr.hpp>
using namespace  boost;


class  A
{
   
public:
   A()  	
   {
   
   	cout << "构造A类对象!" << endl;
   }
   ~A( )  
   {
   
   	cout << "析构A类对象!" << endl;
   } 
   int m_a; 
};

int main()
{
    
   boost::shared_ptr<A>  p1(new  A);// 引用计数+1
   cout << p1.unique() << " , " << p1.use_count() << endl;

   //weak_ptr是 shared_ptr的协助者,或者是一个配角,主要用于观察
   boost::weak_ptr<A>  p2(p1);//不改变引用计数
   cout << p1.unique() << " , " << p1.use_count() << endl;
   cout << p2.expired()/*用于观察shared_ptr指向的内存是否释放 */ << " , " << p2.use_count() << endl;

   //weak_ptr不管理这块内存
   //p2->m_a;//错误的
   //*p2.m_a = 100;//错误的

   boost::shared_ptr<A>  p3(p1);// 引用计数+1
   boost::shared_ptr<A>  p4(p3);// 引用计数+1

   //用weak_ptr来观察一下
   cout << p2.expired()<< " , " << p2.use_count() << endl;

   p1.reset();	 //释放管理权 , 引用计数-1
   p3.reset();	 //释放管理权 , 引用计数-1
   p4.reset();	 //释放管理权 , 引用计数-1,此刻内存释放

   cout << p2.expired() /* 返回1表示内存已经释放*/<< " , " << p2.use_count() << endl;

   return 0;
}

运行结果:

3. weak_ptr运用场景

weak_ptr并不能炸为一个单独指针来使用:不能->访问,*解引用,也不能检查是否为空,它仅仅作为 shared_ptr的观察者。它—般运用于以下场景:

  • 检测管理的内存是否释放

在使用 weak_ptr时,我们一般会先用 expired()判断其是否过期,如果没有过期则可访问所管理的资源,但weak_ptr并不能操作资源(无*->操作),当我们想要访问 weak_ptr,所指向的资源时,应使用lock()方法获取一个shared_ptr,通过 shared_ptr来访问资源。

示例代码:

#include<iostream>
using namespace std;   

#include<boost/weak_ptr.hpp>
#include<boost/shared_ptr.hpp>
using namespace  boost;

class  A
{
   
public:
   A()  	
   {
   
   	cout << "构造A类对象!" << endl;
   }
   ~A( )  
   {
   
   	cout << "析构A类对象!" << endl;
   } 
   int m_a; 
};

int main()
{
    
   boost::shared_ptr<A>  p1(new  A);//引用计数为1
   p1->m_a = 100;

   boost::shared_ptr<A>  p2(p1);//引用计数+1

   cout << p1.use_count() << ","<< p2.use_count() << endl;

   boost::weak_ptr<A>  w1(p1);//不影响引用计数,观察者
   cout << w1.expired()<< "," << w1.use_count() << endl;

   //此刻,让p1释放管理权
   p1.reset();//引用计数-1
   cout << p1.get() << "," << p1.use_count() << endl;

   //通过w1来观察(由此可见,虽然p1放弃了管理权,但是w1依然能正常工作)
   cout << w1.expired() << "," << w1.use_count() << endl;

   if (w1.expired())//观测的内存释放了
   {
   
   	cout << "内存释放了!" << endl;
   }
   else
   {
   
   	//cout << p1->m_a << endl; //错误,已经放弃管理权了
   	//w1->m_a; //错误,weak_ptr不能->, 不能够*

   	boost::shared_ptr<A>   p3=w1.lock(); //可以使用lock返回shared_ptr
   	cout << p3->m_a << endl;
   }

   getchar();
   return 0;
}

运行结果:

  • 解决循环引用问题

示例代码:

#include<iostream>
using namespace std;

#include<boost/weak_ptr.hpp>
#include<boost/shared_ptr.hpp>
using namespace  boost;


class  A
{
   
public:
   A()
   {
   
   	cout << "构造A类对象!" << endl;
   }
   ~A()
   {
   
   	cout << "析构A类对象!" << endl;
   }
    
   //boost::shared_ptr<A>  m_a;  
   boost::weak_ptr<A>  m_a; //解决,因为weak_ptr不会改变引用计数
};


int main()
{
   
   {
   
   boost::shared_ptr<A>  p1(new  A);//引用计数为1
    
   cout << p1.unique() << "," << p1.use_count() << endl;
    
   //现在制造循环引用
   p1->m_a = p1;//   shared_ptr赋值操作,导致引用数+1

   cout << p1.unique() << "," << p1.use_count() << endl;
   } //到这里时候,p1生命周期结束,产生析构,导致引用计数-1,但是注意,2-1>0
     //所以 new A这块内存不会被释放, 所以m_a成员也不会释放,这样就导致了引用计数
   //一直不为0, 则new A的这块内存泄漏

   return 0;
}

运行结果:


转载:https://blog.csdn.net/u014779536/article/details/116401037
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场