- weak_ptr只能从shared_ptr对象构建。
- weak_ptr并不影响动态对象的生命周期,即其存在与否并不影响对象的引用计数器。当weak_ptr所指向的对象因为shared_ptr计数器为0而被释放后,那么weak_ptr的lock方法将返回空。
- weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象。
- 提供了expired()与lock()成员函数,前者用于判断weak_ptr指向的对象是否已被销毁,后者返回其所指对象的shared_ptr智能指针(对象销毁时返回”空“shared_ptr),如果返回shared_ptr,那么计数器会加1.
使用场景
-
1 当你想使用对象,但是并不管理对象,并且在需要时可以返回对象的shared_ptr时,则使用
- 比如,一个A类有两个耗时的加载方法,想在里面线程池来指向,那么就需要穿一个线程池给这个类,但是并不想让A以shared_ptr成员变量来引用这个线程池,所以通过weak_ptr方式就很ok。
-
- 解决shared_ptr的循环引用问题
- 下面代码存在循环引用问题:在这里的b和a的计数都是1,在这里当你进行析构的时候,析构一块空间,会去考虑先释放另外一块空间,然后释放另外一块空间,又要依赖于释放现在的这块空间,这样就会出现一个无限的循环,所以最终的结果是,谁都没有进行释放空间,这样就存在了内存泄漏的问题。
#include <iostream>
#include <memory>
class A;
class B{
public:
~B() {
std::cout << "B destory, a_ptr use_count:" << a_ptr.use_count() << "\n";
}
std::shared_ptr<A> a_ptr;
};
class A{
public:
~A() {
std::cout << "A destory, b_ptr use_count:" << b_ptr.use_count() << "\n";
}
std::shared_ptr<B> b_ptr;
};
int main()
{
std::shared_ptr<A> a(new A());
std::shared_ptr<B> b(new B());
a->b_ptr=b;
b->a_ptr=a;
std::cout << "A:" << a.use_count() << "\n";
std::cout << "B" << b.use_count() << "\n";
}
* 运行结果:
A:2
B:2
- 解决方式,其中一方以weak_ptr方式管理对象。比如把A中对b的指针,使用weak_ptr就可以了。
class A{
public:
~A() {
std::cout << "A destory, b_ptr use_count:" << b_ptr.use_count() << "\n";
}
std::weak_ptr<B> b_ptr;
};
* 运行结果:
A:2
B:1
B destory, a_ptr use_count:2
A destory, b_ptr use_count:0
网友评论