日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++11新特性】 C++11智能指针之weak_ptr

發布時間:2023/11/30 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++11新特性】 C++11智能指针之weak_ptr 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/xiejingfa/article/details/50772571

原創作品,轉載請標明:http://blog.csdn.net/Xiejingfa/article/details/50772571

如題,我們今天要講的是C++11引入的三種智能指針中的最后一個:weak_ptr。在學習weak_ptr之前最好對shared_ptr有所了解。如果你還不知道shared_ptr是何物,可以看看我的另一篇文章【C++11新特性】 C++11智能指針之shared_ptr。


1、為什么需要weak_ptr?

在正式介紹weak_ptr之前,我們先來回憶一下shared_ptr的一些知識。我們知道shared_ptr是采用引用計數的智能指針,多個shared_ptr實例可以指向同一個動態對象,并維護了一個共享的引用計數器。對于引用計數法實現的計數,總是避免不了循環引用(或環形引用)的問題,shared_ptr也不例外。

我們先來看看下面這個例子:

#include <iostream> #include <memory> #include <vector> using namespace std;class ClassB;class ClassA { public:ClassA() { cout << "ClassA Constructor..." << endl; }~ClassA() { cout << "ClassA Destructor..." << endl; }shared_ptr<ClassB> pb; // 在A中引用B };class ClassB { public:ClassB() { cout << "ClassB Constructor..." << endl; }~ClassB() { cout << "ClassB Destructor..." << endl; }shared_ptr<ClassA> pa; // 在B中引用A };int main() {shared_ptr<ClassA> spa = make_shared<ClassA>();shared_ptr<ClassB> spb = make_shared<ClassB>();spa->pb = spb;spb->pa = spa;// 函數結束,思考一下:spa和spb會釋放資源么? }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

上面代碼的輸出如下:

ClassA Constructor... ClassB Constructor... Program ended with exit code: 0
  • 1
  • 2
  • 3

從上面代碼中,ClassA和ClassB間存在著循環引用,從運行結果中我們可以看到:當main函數運行結束后,spa和spb管理的動態資源并沒有得到釋放,產生了內存泄露。

為了解決類似這樣的問題,C++11引入了weak_ptr,來打破這種循環引用。

2、weak_ptr是什么?

weak_ptr是為了配合shared_ptr而引入的一種智能指針,它指向一個由shared_ptr管理的對象而不影響所指對象的生命周期,也就是將一個weak_ptr綁定到一個shared_ptr不會改變shared_ptr的引用計數。不論是否有weak_ptr指向,一旦最后一個指向對象的shared_ptr被銷毀,對象就會被釋放。從這個角度看,weak_ptr更像是shared_ptr的一個助手而不是智能指針。

3、weak_ptr如何使用?

接下來,我們來看看weak_ptr的簡單用法。

3.1如何創建weak_ptr實例

當我們創建一個weak_ptr時,需要用一個shared_ptr實例來初始化weak_ptr,由于是弱共享,weak_ptr的創建并不會影響shared_ptr的引用計數值。

示例:

int main() {shared_ptr<int> sp(new int(5));cout << "創建前sp的引用計數:" << sp.use_count() << endl; // use_count = 1weak_ptr<int> wp(sp);cout << "創建后sp的引用計數:" << sp.use_count() << endl; // use_count = 1 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.2如何判斷weak_ptr指向對象是否存在

既然weak_ptr并不改變其所共享的shared_ptr實例的引用計數,那就可能存在weak_ptr指向的對象被釋放掉這種情況。這時,我們就不能使用weak_ptr直接訪問對象。那么我們如何判斷weak_ptr指向對象是否存在呢?C++中提供了lock函數來實現該功能。如果對象存在,lock()函數返回一個指向共享對象的shared_ptr,否則返回一個空shared_ptr。

示例:

class A { public:A() : a(3) { cout << "A Constructor..." << endl; }~A() { cout << "A Destructor..." << endl; }int a; };int main() {shared_ptr<A> sp(new A());weak_ptr<A> wp(sp);//sp.reset();if (shared_ptr<A> pa = wp.lock()){cout << pa->a << endl;}else{cout << "wp指向對象為空" << endl;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

試試把sp.reset()這行的注釋去掉看看結果有什么不同。

除此之外,weak_ptr還提供了expired()函數來判斷所指對象是否已經被銷毀。

示例:

class A { public:A() : a(3) { cout << "A Constructor..." << endl; }~A() { cout << "A Destructor..." << endl; }int a; };int main() {shared_ptr<A> sp(new A());weak_ptr<A> wp(sp);sp.reset(); // 此時sp被銷毀cout << wp.expired() << endl; // true表示已被銷毀,否則為false }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

代碼輸入如下:

A Constructor... A Destructor... 1
  • 1
  • 2
  • 3

3.3如何使用weak_ptr

weak_ptr并沒有重載operator->和operator *操作符,因此不可直接通過weak_ptr使用對象,典型的用法是調用其lock函數來獲得shared_ptr示例,進而訪問原始對象。

最后,我們來看看如何使用weak_ptr來改造最前面的代碼,打破循環引用問題。

class ClassB;class ClassA { public:ClassA() { cout << "ClassA Constructor..." << endl; }~ClassA() { cout << "ClassA Destructor..." << endl; }weak_ptr<ClassB> pb; // 在A中引用B };class ClassB { public:ClassB() { cout << "ClassB Constructor..." << endl; }~ClassB() { cout << "ClassB Destructor..." << endl; }weak_ptr<ClassA> pa; // 在B中引用A };int main() {shared_ptr<ClassA> spa = make_shared<ClassA>();shared_ptr<ClassB> spb = make_shared<ClassB>();spa->pb = spb;spb->pa = spa;// 函數結束,思考一下:spa和spb會釋放資源么? }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

輸出結果如下:

ClassA Constructor... ClassB Constructor... ClassA Destructor... ClassB Destructor... Program ended with exit code: 0
  • 1
  • 2
  • 3
  • 4
  • 5

從運行結果可以看到spa和spb指向的對象都得到釋放!


總結

以上是生活随笔為你收集整理的【C++11新特性】 C++11智能指针之weak_ptr的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。