用std::weak_ptr观测std::shared_ptr的内部状态¶
std::weak_ptr 不能解引用,它不是一种独立的智能指针,而是 std::shared_ptr 的一种扩充,它用std::shared_ptr初始化,共享对象但不改变引用计数,主要作用是观察 std::shared_ptr 的内部状态。
std::weak_ptr<int> w;
void f(std::weak_ptr<int> w)
{
if (auto p = w.lock()) std::cout << *p << "\n";
else std::cout << "can't get value" << "\n";
}
int main()
{
{
auto p = std::make_shared<int>(42);
w = p;
assert(p.use_count() == 1);
assert(w.expired() == false);
f(w); //@ 42
auto q = w.lock();
assert(p.use_count() == 2);
assert(q.use_count() == 2);
}
f(w); //@ can't get value
assert(w.expired() == true);
assert(w.lock() == nullptr);
}
std::weak_ptr 的另一个作用是解决循环引用问题:
class B;
class A {
public:
std::shared_ptr<B> b;
};
class B {
public:
std::shared_ptr<A> a; //@ std::weak_ptr<A> a;
};
int main()
{
{
std::shared_ptr<A> x(new A);
x->b = std::shared_ptr<B>(new B);
x->b->a = x;
} //@ x.use_count由2减为1,不会析构,于是x->b也不会析构,导致两次内存泄漏
//@ 如果B::a改为std::weak_ptr,则use_count不会为2而保持1,此处就会由1减为0,从而正常析构
}