基本用法
弱引用weak_ptr主要是监视shared_ptr,不会使引用计数增加。
基本用法如下:
std::weak_ptr<int> rptr;
void testFunction()
{
if (rptr.expired())
{
cout << "shared_ptr release" << endl;
}
else
{
auto sptr = rptr.lock();
cout << "value:" << *sptr << endl;
}
}
int main()
{
{
std::shared_ptr<int> ptr(new int(1));
rptr = ptr;
cout << "use count:" << ptr.use_count() << endl; //弱引用不增加引用计数
testFunction();
}
testFunction();
return 0;
}
通过expired来判断所观察的资源是否被释放。lock方法获取所监视的资源的shared_ptr。
weak_ptr返回this指针
在shared_ptr中返回this指针需要继承enable_shared_from_this。通过shared_from_this来返回一个指针指针,原因是enable_shared_from_this有一个weak_ptr,这个ptr用来监视this指针。调用方法后会调用ptr的lock方法返回监测的shared_ptr。
struct A : public enable_shared_from_this<A>
{
std::shared_ptr<A> getSelf()
{
return shared_from_this();
}
};
//use
std::shared_ptr<A> sptr(new A);
cout << "use count:" << sptr.use_count() << endl;
std::shared_ptr<A> ptr = sptr->getSelf();
cout << "use count:" << sptr.use_count() << endl;
这里有个特别要注意的:在外面创建的A对象的指针指针和通过该对象返回的this的指针指针都是安全的,因为通过shared_from_this是内部的weak_ptr调用lock之后返回的智能指针,在离开作用域后,sptr的计数器最终减为0,A被析构,且析构一次。
但是如下面操作:
struct A //: public enable_shared_from_this<A>
{
std::shared_ptr<A> getSelf()
{
//return shared_from_this();
return std::shared_ptr<A>(this);
}
};
就是不会对原有的智能指针引用计数增加(两者没有关联),最终导致A被析构两次。
最后要注意的是,获取自身智能指针的函数仅在shared_ptr的构造函数被调用之后才能被使用,因为内部的weak_ptr只有通过shared_ptr才能被构造;
weak_ptr解决循环引用问题
同shared_ptr的部分,但是有所修改。
struct B;
struct C;
struct B
{
std::shared_ptr<C> cptr;
~B()
{
cout << "delete B" << endl;
}
};
struct C
{
std::weak_ptr<B> bptr;
~C()
{
cout << "delete C" << endl;
}
};
//使用如下
std::shared_ptr<B> bptr(new B);
std::shared_ptr<C> cptr(new C);
bptr->cptr = cptr;
cptr->bptr = bptr;