文章目录

weak_ptr介绍

弱引用指针weak_ptr是用来监视shared_ptr的生命周期,是shared_ptr的一个助手。weak_ptr没有重载操作符*和->,因为它不与shared_ptr共享指针,不能操作资源

weak_ptr主要是通过lock方法转换成shared_ptr获得资源的监测权,它的构造不会增加引用计数Uses_,它的析构也不会减少引用计数Uses_,纯粹只是作为一个旁观者来监视shared_ptr中管理的资源是否存在。weak_ptr还可以用来返回this指针和解决循环引用的问题

weak_ptr 构造

只能用shared_ptr对象或者weak_ptr对象初始化weak_ptr,不能用裸指针初始化weak_ptr。由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值Uses_。可以通过use_count()方法来获得当前被管理资源的引用计数Uses_,即管理资源的shared_ptr的数量

  • Uses_:管理资源的shared_ptr的数量,Uses_为0时释放被管理的资源
  • Weaks_:shared_ptr被构造时为1,多一个weak_ptr指向则加1,少一个weak_ptr指向则减1;多一个或少一个shared_ptr指向都不变,只有当Uses_减为0时,才会将Weaks_减1

【示例一】

<Int> sp1(new Int(10));    // Uses_ = 1,Weaks_ = 1
weak_ptr<Int> wp(sp1); // Uses_ = 1,Weaks_ = 2
cout << wp.use_count() << endl; // 1
{
shared_ptr<Int> sp2(sp1); // 拷贝构造
cout << wp.use_count() << endl; // // Uses_ = 2,Weaks_ = 2
} // sp2析构时,会将Uses_从2减为1,此时Weaks_也从2减为1,Uses_ = 1,Weaks_ = 1
cout << wp.use_count() << endl; // 1

shared_ptr析构时会将引用计数对象的Uses_减1,而不会改变Weaks_,只有当Uses_减为0时,才会将Weaks_减1。Uses_为0时释放被管理的资源,Uses_和Weaks_同时为0时释放引用计数对象。weak_ptr析构时会将Weaks_减1

C++11智能指针weak_ptr_拷贝构造

【示例二】

<Int> wp;
cout << wp.use_count() << endl; // 还没有创建引用计数对象,该函数会直接返回0
{
shared_ptr<Int> sp(new Int(10)); // Uses_ = 1,Weaks_ = 1
wp = sp; // weak_ptr& operator=(const shared_ptr<_Ty2>& _Right) Uses_ = 1,Weaks_ = 2
cout << wp.use_count() << endl; // 1
} // sp析构时,会将Uses_从1减为0,此时Weaks_也从2减为1,Uses_ = 0,Weaks_ = 1
cout << wp.use_count() << endl; // 0

expired函数,当引用计数对象Uses_不为0时返回true,否则返回false

lock方法

weak_ptr没有重载operator*和operator->操作符,不能直接操作资源,需要调用lock方法或者shared_ptr实例才能访问资源

weak_ptr<Int> gw;

void func() {
if (!gw.expired()) {
cout << "not expired" << endl;
shared_ptr<Int> sp2 = gw.lock(); // Uses_ = 2,Weaks_ = 2
sp2->show_value();
}
else {
cout << "expired" << endl;
}
}

int main() {
shared_ptr<Animal>
{
shared_ptr<Int> sp1(new Int(1)); // Uses_ = 1,Weaks_ = 1
gw = sp1; // Uses_ = 1,Weaks_ = 2
func(); // func退出后,sp2 构,Uses_ = 1,Weaks_ = 1
} // 局部作用域退出后,sp1析构,Uses_ = 0,Weaks_ = 1,资源释放,引用计数对象没释放

func();
return 0;
}
int main() {
weak_ptr<Int> wp;
{
shared_ptr<Int> sp1(new Int(10)); // Uses_ = 1,Weaks_ = 2,引用计数对象构造时,Uses_和Weaks_直接被初始化为1
wp = sp1; // Uses_ = 1,Weaks_ = 2
shared_ptr<Int> sp2(sp1); // 左值引用拷贝构造,Uses_ = 2,Weaks_ = 2
{
shared_ptr<Int> sp3(sp1); // 左值引用拷贝构造,Uses_ = 3,Weaks_ = 2
cout << wp.use_count() << endl; // 3
} // sp3析构,Uses_ = 2,Weaks_ = 2
} // sp2和sp1都析构,Uses_ = 0,Weaks_ = 1
if (!wp.expired()) {
cout << wp.use_count() << endl; // Uses_ = 0,进入if
}
return 0;
}