智能指针weak_ptr对shared_ptr管理的对象存在弱引用,即weak_ptr并不会增加引用对象的引用计数。weak_ptr是对shared_ptr的一种"观察",可以检查shared_ptr管理对象的是否被删除以及引用计数等,但是weak_ptr不能直接使用引用的对象,需要使用lock接口创建其引用对象的shared_ptr。
文章的代码库为:
https://gitee.com/gamestorm577/CppStd
构造函数
weak_ptr可以的构造函数参数可以是weak_ptr或者shared_ptr,例如:
std::shared_ptr<int> sptr = std::make_shared<int>();
std::weak_ptr<int> wptr1(sptr);
std::weak_ptr<int> wptr2(wptr1);
printf("sptr use count = %ld\n", sptr.use_count());
输出结果为:
sptr use count = 1
wptr1和wptr2引用了sptr,但并没有改变sptr的引用计数。
析构函数
销毁weak_ptr对象不会对其引用的对象产生影响
赋值函数
和构造函数一样,赋值函数的参数可以是weak_ptr或者shared_ptr,赋值操作不会对引用的shared_ptr造成影响。
查看引用计数
使用use_count接口可以查看weak_ptr引用对象的引用计数,例如:
std::shared_ptr<int> sptr1 = std::make_shared<int>();
std::shared_ptr<int> sptr2 = sptr1;
std::weak_ptr<int> wptr = sptr1;
printf("wptr use count = %ld\n", wptr.use_count());
输出结果为:
wptr use count = 2
查看引用对象是否被删除
使用expired接口可以查看weak_ptr引用的对象是否已经被删除,例如:
std::weak_ptr<int> wptr;
{
std::shared_ptr<int> sptr = std::make_shared<int>();
wptr = sptr;
printf("Is sptr expired: %d\n", wptr.expired());
}
printf("Is sptr expired: %d\n", wptr.expired());
输出结果为:
Is sptr expired: 0
Is sptr expired: 1
创建被引用的对象
weak_ptr不能直接使用引用的对象,如果需要使用,可以用lock接口创建其引用对象的shared_ptr,例如:
auto FuncObserve = [](std::weak_ptr<int> wptr) -> void
{
auto observe = wptr.lock();
if (observe)
{
printf("number = %d\n", *observe);
}
else
{
printf("lock return null\n");
}
};
std::weak_ptr<int> wptr;
{
std::shared_ptr<int> sptr = std::make_shared<int>(25);
wptr = sptr;
FuncObserve(wptr);
}
FuncObserve(wptr);
输出结果为:
number = 25
lock return null
其他接口
reset
释放引用对象的所有权,对shared_ptr没有影响,例如:
std::shared_ptr<int> sptr = std::make_shared<int>();
std::weak_ptr<int> wptr = sptr;
printf("sptr use count = %ld\n", sptr.use_count());
printf("wptr use count = %ld\n", wptr.use_count());
wptr.reset();
printf("sptr use count = %ld\n", sptr.use_count());
printf("wptr use count = %ld\n", wptr.use_count());
输出结果为:
sptr use count = 1
wptr use count = 1
sptr use count = 1
wptr use count = 0
swap
交换引用的对象,引用的shared_ptr不受影响,例如:
std::shared_ptr<int> sptr1 = std::make_shared<int>(5);
std::weak_ptr<int> wptr1 = sptr1;
std::shared_ptr<int> sptr2 = std::make_shared<int>(25);
std::weak_ptr<int> wptr2 = sptr2;
printf("Before swap: \n");
printf("wptr1 number = %d\n", *wptr1.lock());
printf("wptr2 number = %d\n", *wptr2.lock());
wptr1.swap(wptr2);
printf("After swap: \n");
printf("wptr1 number = %d\n", *wptr1.lock());
printf("wptr2 number = %d\n", *wptr2.lock());
输出结果为:
Before swap:
wptr1 number = 5
wptr2 number = 25
After swap:
wptr1 number = 25
wptr2 number = 5
owner_before
判断第一个weak_ptr引用的shared_ptr获取对象的顺序,例如:
std::shared_ptr<int> sptr1 = std::make_shared<int>();
std::shared_ptr<int> sptr2 = sptr1;
std::shared_ptr<int> sptr3 = std::make_shared<int>();
std::weak_ptr<int> wptr1 = sptr1;
std::weak_ptr<int> wptr2 = sptr2;
std::weak_ptr<int> wptr3 = sptr3;
printf("wptr1 owner before wptr2: %d\n", wptr1.owner_before(wptr2));
printf("wptr1 owner before wptr3: %d\n", wptr1.owner_before(wptr3));
wptr1 owner before wptr2: 0
wptr1 owner before wptr3: 1