智能指針 weak_ptr 使用 weak_ptr用途: 1,解決空懸指針問題 2,解決迴圈引用問題 weak_ptr特點:沒有 操作和 操作 weak_ptr是不控制所指對象生存周期的智能指針,它指向由一個shared_ptr管理的對象。將一個weak_ptr綁定到一個shared_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;
}