C++智能指针之weak_ptr

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
}

上一篇:R语言HAR和HEAVY模型分析高频金融数据波动率


下一篇:SQL Server 2008 复习(一)