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_ptr
与 boost::weak_ptr
功能相似。
shared_ptr
构造或析构导致引用计数加减1
,而weak_ptr
不会引起引用计数的改变。
shared_ptr
与weak_ptr
的区别:
区别 | weak_ptr |
shared_ptr |
---|---|---|
构造 | weak_ptr 、shared_ptr 构造 |
new 、shared_ptr 构造 |
指针功能 | 不支持* 、-> 操作符重载 |
支持* 、-> 操作符重载 |
引用计数改变 | 不影响对应的shared_ptr 内部计数 |
改变引用计数 |
成员函数 | use_count 返回引用计数expired 检测所管理的对象是否释放reset 将weak_ptr 置空swap 交换两个shared_ptr 对象lock 创建新的shared_ptr 对象并使计数+1 |
use_count 返回引用计数unique 返回是否独占所有权reset 放弃所有权并使计数-1swap 交换两个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