欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11智能指針之weak_ptr詳解

 更新時間:2020年06月09日 09:01:40   作者:音視頻開發(fā)進階  
這篇文章主要介紹了 C++11智能指針之weak_ptr詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

如題,我們今天要講的是 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是采用引用計數(shù)的智能指針,多個shared_ptr實例可以指向同一個動態(tài)對象,并維護了一個共享的引用計數(shù)器。

對于引用計數(shù)法實現(xiàn)的計數(shù),總是避免不了循環(huán)引用(或環(huán)形引用)的問題,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;
 // 函數(shù)結束,思考一下:spa和spb會釋放資源么?
}

上面代碼的輸出如下:

ClassA Constructor...
ClassB Constructor...
Program ended with exit code: 0

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

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

2、weak_ptr是什么?

weak_ptr 是為了配合 shared_ptr 而引入的一種智能指針,它指向一個由 shared_ptr 管理的對象而不影響所指對象的生命周期,也就是將一個 weak_ptr 綁定到一個 shared_ptr 不會改變 shared_ptr 的引用計數(shù)。

不論是否有 weak_ptr 指向,一旦最后一個指向?qū)ο蟮?shared_ptr 被銷毀,對象就會被釋放。

從這個角度看,weak_ptr更像是shared_ptr的一個助手而不是智能指針。

3、weak_ptr如何使用?

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

3.1如何創(chuàng)建weak_ptr實例

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

示例:

int main() {
 shared_ptr<int> sp(new int(5));
 cout << "創(chuàng)建前sp的引用計數(shù):" << sp.use_count() << endl; // use_count = 1

 weak_ptr<int> wp(sp);
 cout << "創(chuàng)建后sp的引用計數(shù):" << sp.use_count() << endl; // use_count = 1
}

3.2如何判斷weak_ptr指向?qū)ο笫欠翊嬖?/p>

既然weak_ptr并不改變其所共享的shared_ptr實例的引用計數(shù),那就可能存在weak_ptr指向的對象被釋放掉這種情況。

這時,我們就不能使用weak_ptr直接訪問對象。那么我們?nèi)绾闻袛鄔eak_ptr指向?qū)ο笫欠翊嬖谀兀?/p>

C++中提供了lock函數(shù)來實現(xiàn)該功能。

如果對象存在,lock()函數(shù)返回一個指向共享對象的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指向?qū)ο鬄榭? << endl;
 }
}

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

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

示例:

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
}

代碼輸入如下:

A Constructor...
A Destructor...
1

3.3如何使用weak_ptr

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

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

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;
 // 函數(shù)結束,思考一下:spa和spb會釋放資源么?
}

輸出結果如下:

ClassA Constructor...
ClassB Constructor...
ClassA Destructor...
ClassB Destructor...
Program ended with exit code: 0

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

總結

到此這篇關于C++11智能指針之weak_ptr詳解的文章就介紹到這了,更多相關C++11智能指針 weak_ptr內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • swift Character類型詳解及實例

    swift Character類型詳解及實例

    這篇文章主要介紹了 swift Character類型詳解及實例的相關資料,需要的朋友可以參考下
    2017-06-06
  • C++中讀寫txt文件并分離字符的方法

    C++中讀寫txt文件并分離字符的方法

    今天小編就為大家分享一篇C++中讀寫txt文件并分離字符的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • C++實現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法

    C++實現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法

    這篇文章主要介紹了C++實現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法,對于C++程序算法設計有一定的借鑒價值,需要的朋友可以參考下
    2014-09-09
  • C++使用正則表達式的詳細教程

    C++使用正則表達式的詳細教程

    正則表達式是一個非常強大的工具,主要用于字符串匹配,下面這篇文章主要給大家介紹了關于C++使用正則表達式的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • C++類與對象的基礎知識點詳細分析

    C++類與對象的基礎知識點詳細分析

    類和對象是兩種以計算機為載體的計算機語言的合稱。對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲在內(nèi)存中—個可以擁有在某個范圍內(nèi)的可變存儲區(qū)域
    2023-02-02
  • win32 api實現(xiàn)2048游戲示例

    win32 api實現(xiàn)2048游戲示例

    這篇文章主要介紹了win32 api實現(xiàn)2048游戲示例,需要的朋友可以參考下
    2014-05-05
  • C++實現(xiàn)投骰子的隨機游戲

    C++實現(xiàn)投骰子的隨機游戲

    這篇文章主要為大家詳細介紹了C++實現(xiàn)投骰子的隨機游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 探討register關鍵字在c語言和c++中的差異

    探討register關鍵字在c語言和c++中的差異

    建議不要用register關鍵字定義全局變量,因為全局變量的生命周期是從執(zhí)行程序開始,一直到程序結束才會終止,而register變量可能會存放在cpu的寄存器中,如果在程序的整個生命周期內(nèi)都占用著寄存器的話,這是個相當不好的舉措
    2013-10-10
  • 利用QT實現(xiàn)圖片瀏覽器的示例詳解

    利用QT實現(xiàn)圖片瀏覽器的示例詳解

    這篇文章主要和大家分享一個小案例:利用QT制作一個小的圖片瀏覽器,要求可以顯示jpg、jpeg、png、bmp,還可以從電腦上拖動圖到窗口并顯示出來,感興趣的可以了解一下
    2023-02-02
  • C++共享內(nèi)存刪除的陷阱

    C++共享內(nèi)存刪除的陷阱

    這篇文章主要介紹了C++共享內(nèi)存刪除的陷阱講解,當進程結束使用共享內(nèi)存區(qū)時,要通過函數(shù) shmdt 斷開與共享內(nèi)存區(qū)的連接。下面來看看具體問題都是怎么解決的吧
    2022-01-01

最新評論