c++中的weak_ptr的使用与理解
weak_ptr 的使用
\(\quad\)关于为什么使用 weak_ptr
,以及他的使用场景,我们在这篇文章中已经进行了介绍。而对于其具体的使用方法,比如说如何通过 weak_ptr
访问内存中的数据等操作还未提及,这里做个简单赘述。
\(\quad\)有一句话说的很好: weak_ptr
就像观测者那样观测资源的使用情况。
- 首先,
weak_ptr
是配合shared_ptr
的使用,weak_ptr
可以用shared_ptr
来赋值,但当它引用shared_ptr
时并不会引起它的计数。 - 另外,
weak_ptr
并没有重载解引用等操作符,也不单独使用(不能单独使用的原因是,weak_ptr
没有重载解引用*、->运算符,也就是说它只能访问但不能修改)。 - 使用
expired()
检查weak_ptr
的引用情况(expired()==true
时表示资源已被释放),使用lock()
获取一个shared_ptr
的对象。
和 shared_ptr
、unique_ptr
相比,weak_ptr
模板类提供的成员方法不多,以下是常用的成员方法及各自的功能:
- operator=():重载 = 赋值运算符,是的
weak_ptr
指针可以直接被weak_ptr
或者shared_ptr
类型指针赋值。 - swap(x):其中 x 表示一个同类型的
weak_ptr
类型指针,该函数可以互换 2 个同类型weak_ptr
指针的内容。 - reset():将当前
weak_ptr
指针置为空指针。 - use_count():查看指向和当前
weak_ptr
指针相同的shared_ptr
指针的数量。 - expired():判断当前
weak_ptr
指针为否过期(指针为空,或者指向的堆内存已经被释放)。 - lock():如果当前
weak_ptr
已经过期,则该函数会返回一个空的shared_ptr
指针;反之,该函数返回一个和当前weak_ptr
指向相同的shared_ptr
指针。
示例程序
#include <iostream>
#include <memory>
void observe(std::weak_ptr<int> weak)
{
if (auto observe = weak.lock()) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}
int main()
{
std::weak_ptr<int> weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);
{
auto shared = std::make_shared<int>(42);
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
std::cout << "weak_ptr<> use_count() "<< weak.use_count() << ".\n";
std::weak_ptr<int> weak2;
weak2 = weak;
std::cout << "after weak_ptr assignment, use_count is "<< weak.use_count() << ".\n";
weak.reset();
if (weak.expired())
std::cout << "weak_ptr expired, con not use\n";
}
std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}
输出如下:
weak_ptr<> not yet initialized
observe() unable to lock weak_ptr<>
weak_ptr<> initialized with shared_ptr.
observe() able to lock weak_ptr<>, value=42
weak_ptr<> use_count() 1.
after weak_ptr assignment, use_count is 1.
weak_ptr expired, con not use
shared_ptr<> has been destructed due to scope exit.
observe() unable to lock weak_ptr<>