文章目录
1.weak_ptr概述
weak_ptr 是一种不控制所指向对象生存期的智能指针,它指向由一个 shared_ptr 管理的对象。
将一个 weak_ptr 绑定到一个 shared_ptr 不会改变 shared_ptr 的引用计数,更确切地说,weak_ptr 的构造和析构不会增加或减少所指向对象的引用计数。
一旦最后一个指向对象的 shared_ptr 被销毁,对象就会被释放,即使有 weak_ptr 指向对象,对象也还是会被释放,因此,weak_ptr 的名字抓住了这种智能指针“弱”共享对象的特点。
weak_ptr 不是一种独立的智能指针,不能用来操作所指向的资源,所以它看起来像是 shared_ptr 的助手。weak_ptr 能够监视到它所指向的对象是否存在。
2.weak_ptr的创建
当我们创建一个 weak_ptr 时,要用一个 shared_ptr 来初始化它:
#include <iostream>
using namespace std;
int main()
{
auto sp = make_shared<int>(100); // 强引用计数从0变1
weak_ptr<int> wp(sp); // wp弱共享sp,强引用计数仍为1,弱引用计数从0变1
return 0;
}
强引用计数才能决定对象的生存期,弱引用计数对对象的生存期没有影响。
2.1 lock()
由于对象可能不存在,我们不能使用 weak_ptr 直接访问对象,而必须调用 lock() 函数。
lock() 的功能就是检查 weak_ptr 所指向的对象是否存在,如果存在,则返回一个指向该对象的 shared_ptr,同时指向该对象的强引用计数就会加 1 1 1;如果不存在,则返回一个空的 shared_ptr。
#include <iostream>
using namespace std;
int main()
{
auto sp = make_shared<int>(100); // 强引用计数从0变1
weak_ptr<int> wp(sp); // wp弱共享sp,强引用计数仍为1,弱引用计数从0变1
auto sp2 = wp.lock(); // 强引用计数从1变2,弱引用计数仍为1
if (sp2)
{
cout << "wp所指向的对象存在" << endl;
*sp2 = 200;
}
else
{
cout << "wp所指向的对象不存在" << endl;
}
return 0;
}
3.weak_ptr的常用操作
3.1 use_count()
w.use_count()
:返回与 w 共享对象的 shared_ptr 的数量。
#include <iostream>
using namespace std;
int main()
{
auto sp1 = make_shared<int>(100);
auto sp2(sp1);
weak_ptr<int> wp(sp1);
cout << wp.use_count() << endl; // 2
return 0;
}
3.2 expired()
w.expired()
:判断是否过期。若 w.use_count()
为
0
0
0,表示该弱指针所指向的对象已经不存在了,则返回 true,否则返回 false。
#include <iostream>
using namespace std;
int main()
{
auto sp = make_shared<int>(100);
weak_ptr<int> wp(sp);
cout << wp.use_count() << endl; // 1
sp.reset();
cout << wp.use_count() << endl; // 0
if (wp.expired()) cout << "所指对象已经过期" << endl;
else cout << "所指对象没有过期" << endl;
return 0;
}
3.3 reset()
w.reset()
:将该弱引用指针设置为空,不影响指向该对象的强引用数量,但指向该对象的弱引用数量会减少
1
1
1。
#include <iostream>
using namespace std;
int main()
{
auto sp1 = make_shared<int>(100); // 强引用计数从0变1
auto sp2(sp1); // 强引用计数从1变2
weak_ptr<int> wp(sp1); // 强引用计数仍为2,弱引用计数从0变1
cout << wp.use_count() << endl; // 2
wp.reset(); // 强引用计数仍为2,弱引用计数从1变0
cout << sp1.use_count() << endl; // 2
return 0;
}
4.weak_ptr的尺寸
weak_ptr 的尺寸和 shared_ptr 的尺寸一样大,都是裸指针的 2 倍。
#include <iostream>
using namespace std;
int main()
{
int* p;
cout << sizeof(p) << endl; // x86:4,x64:8
weak_ptr<int> wp;
cout << sizeof(wp) << endl; // x86:8,x64:16
return 0;
}