1、weak_ptr 的存在是为了协助 share_ptr 的,weak_ptr 指向 share_ptr 管理的对象。
2、weak_ptr 指向 share_ptr 管理的对象不会改变 share_ptr 的引用计数。
3、weak_ptr 的 use_count() 返回的是指向的 share_ptr 的引用计数。
4、weak_ptr 不具有普通指针的行为,没有重载 operator* 和 ->。
5、expired() 获取指向的 share_ptr 的引用计数为是否为0。
6、lock():
- expired()为true,返回nullptr
- expired()为false,返回指向的 share_ptr
这可以用来检测对应 share_ptr 指向的对象是不是存在。
7、share_ptr 进行 reset() 会使 weak_ptr 指向的内容清空:
#define debug qDebug()<<
int main(int argc, char *argv[])
{
std::shared_ptr<int> sptr = std::make_shared<int>(10);
std::weak_ptr<int> weak1 = sptr;
sptr.reset(new int(5));
if(std::shared_ptr<int> tmp = weak1.lock())
debug *tmp;
else
debug "weak1已过期了";
std::weak_ptr<int> weak2 = sptr;
if(auto tmp = weak2.lock())
debug *tmp;
else
debug "weak2已过期了";
}
8、使用场景。由于 share_ptr 是很完善的智能指针,weak_ptr 的唯一合理的使用场景就是在 share_ptr 会形成循环引用的地方使用weak_ptr 代替 share_ptr。
class A;
class B
{
public:
std::shared_ptr<A> a_ptr;
};
class A
{
public:
std::shared_ptr<B> b_ptr;
};
int main(int argc, char *argv[])
{
std::shared_ptr<A> a(new A());
std::shared_ptr<B> b(new B());
a->b_ptr = b;
b->a_ptr = a;
}
上面的代码形成了循环引用。
有两个 share_ptr 指针指向 new A()申请的内存,两个 share_ptr 指针指向 new B()申请的内存。
当执行完主函数时,清除智能指针 std::shared_ptr<B> b,但是原先b指向的内存还有一个a->b_ptr在指着,引用计数 == 1,所以该内存不会被删除。
a也同理,删除a时,由于原先b指向的内存无法删除,所以始终有个a_ptr指着a的内存,导致a指向的内存引用计数不为0。
解决办法是其中一方改用 weak_ptr 。