c/c++ 智能指針 weak_ptr 使用


智能指針 weak_ptr 使用

weak_ptr用途:

1,解決空懸指針問題

2,解決循環引用問題

weak_ptr特點:沒有*操作和->操作


weak_ptr是不控制所指對象生存周期的智能指針,它指向由一個shared_ptr管理的對象。將一個weak_ptr綁定到一個shared_ptr不會改變shared_ptr的計數器。一旦最后一個指向對象的shared_ptr被銷毀,對象就會被釋放,即使有weak_ptr指向這個對象,對象也會被釋放。

一,先來個表格,嘮嘮weak_ptr

操作 功能描述
weak_ptr<T> w 空weak_ptr,可以指向類型為T*的對象。
weak_ptr<T> w(sp) 與shared_sp 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。

小例子索引

代碼塊 功能描述
test1 weak_ptr不增加引用計數
test2 weak_ptr沒有->和*操作
test3 lock使用
test4 循環引用,導致即使是智能指針也不能釋放內存。用weak_ptr解決了循環引用,導致的內存不能釋放的問題

小例子

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

class Test{
public:
  Test(int d = 0) : data(d){cout << "new" << data << endl;}
  ~Test(){cout << "del" << data << endl;}
  void func(){cout << "func" << endl;}
private:
  int data;
};

//test4 循環引用,導致即使是智能指針也不能釋放內存                              
class teacher;
class student;
class teacher{
public:
  teacher(){cout << "teacher()" << endl;}
  ~teacher(){cout << "del teacher" << endl;}
  shared_ptr<student> stu;
};
class student{
public:
  student(){cout << "student()" << endl;}
  ~student(){cout << "del student" << endl;}
  //如果換成shared_ptr<teacher> tea;就會形成循環引用,導致內存泄漏    
  weak_ptr<teacher> tea;
};
int main(){
  //test1 weak_ptr不增加引用計數                                                
  /*                                                                            
  shared_ptr<Test> sp1 = make_shared<Test>(1);                                  
  cout << sp1.use_count() << endl;//1                                           
  weak_ptr<Test> wp1 = sp1;                                                     
  cout << wp1.use_count() << endl;//1                                           
  */

  //test2 weak_ptr沒有->和*操作                                                 
  //wp1->func();                                                                
  //(*wp1).func();                                                              

  //test3 lock使用                                                              
  /*                                                                            
  shared_ptr<int> sptr;                                                         
  sptr.reset(new int);                                                          
  *sptr = 10;                                                                   
  weak_ptr<int> weak1 = sptr;                                                   
  sptr.reset(new int);                                                          
  *sptr = 5;                                                                    
  weak_ptr<int> weak2 = sptr;                                                   
  // weak1 is expired!                                                          
  if(auto tmp = weak1.lock())                                                   
    cout << *tmp << '\n';                                                       
  else                                                                          
    cout << "weak1 is expired\n";                                               
  // weak2 points to new data (5)                                               
  if(auto tmp = weak2.lock())                                                   
    cout << *tmp << '\n';                                                       
  else                                                                          
    cout << "weak2 is expired\n";                                               
  */

  //test4 循環引用,導致即使是智能指針也不能釋放內存                            
  //用weak_ptr解決了循環引用,導致的內存不能釋放的問題                          
  shared_ptr<teacher> tptr(new teacher);//計數器1                               
  shared_ptr<student> sptr(new student);//計數器1                               
  tptr->stu = sptr;//sptr的計數器2                                              
  sptr->tea = tptr;//不增加tptr的引用計數,因為tea是weak指針                     
  cout << tptr.use_count() << endl;//1                                          
  cout << sptr.use_count() << endl;//2                                          

  return 0;
}

github完整代碼

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM