weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象会被释放。即使有weak_ptr指向对象,对象也会被释放,因此,weak_ptr的名字抓住了这种智能指针“弱”共享对象的特点。
weak_ptr | |
---|---|
weak_ptr<T> w | 空weak_ptr可以指向类型为T的对象 |
weak_ptr<T> w(sp) | 与shared_ptr sp指向相同对象的weak_ptr。T必须能转换为sp指向的类型 |
w = p | p可以是一个shared_ptr或一个weak_ptr。赋值后w与p共享对象 |
w.reset() | 将w置为空 |
w.use_count() | 与w共享对象的shared_ptr的数量 |
w.expired() | 若w.use_count()为0,返回true,否则返回false |
w.lock() | 如果expired为true,返回一个空shared_ptr;否则返回一个指向w的对象的shared_ptr |
当我们创建一个weak_ptr时,要用一个shared_ptr来初始化它:
auto p = make_shared<int>(42); weak_ptr<int> wp(p); //wp弱引用p,p的引用计数未改变,wp指向的对象可能被释放掉
由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock.此函数检查weak_ptr指向的对象是否存在,如果存在,lock返回一个指向共享对象的shared_ptr。
if(shared_ptr<int> np = wp.lock()) { //如果np不为空则条件成立 //在if中,np与p共享对象 }
//WeakPtr.h #include "SharedPtr.h" class WeakPtr { public: WeakPtr() :curr(0) {} WeakPtr(SharedPtr &a, std::size_t size = 0): wptr(a.data), curr(size){} std::string &deref() const; WeakPtr& incr(); //前缀递增 private: //若检查成功,check返回一个指向vector的shared_ptr std::shared_ptr<std::vector<std::string>> check(std::size_t i, const std::string &msg) const; //保存一个weak_ptr,意味着底层vector可能会被销毁 std::weak_ptr<std::vector<std::string>> wptr; std::size_t curr; //在数组中的当前位置 }; //WeakPtr.cpp #include "WeakPtr.h" std::string & WeakPtr::deref() const { auto p = check(curr, "deference past end"); return (*p)[curr]; //(*p)是对象所指向的vector } WeakPtr& WeakPtr::incr() { //如果curr已经指向容器的尾后位置,就不能递增它 check(curr, "deference past end"); ++curr; return *this; //(*p)是对象所指向的vector } std::shared_ptr<std::vector<std::string>> WeakPtr::check(std::size_t i, const std::string &msg) const { auto ret = wptr.lock(); if (!ret) throw std::runtime_error("unbound WeakPtr"); if (i > ret->size()) throw std::out_of_range(msg); return ret; //否则 返回指向vector的shared_ptr }