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

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

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

如題,我們今天要講的是 C++11 引入的三種智能指針中的:weak_ptr。

在學(xué)習(xí) weak_ptr 之前最好對(duì) shared_ptr 有所了解。如果你還不知道 shared_ptr 是何物,可以看看另一篇文章:

【C++11新特性】 C++11智能指針之shared_ptr

1、為什么需要weak_ptr?

在正式介紹weak_ptr之前,我們先來(lái)回憶一下shared_ptr的一些知識(shí)。

我們知道shared_ptr是采用引用計(jì)數(shù)的智能指針,多個(gè)shared_ptr實(shí)例可以指向同一個(gè)動(dòng)態(tài)對(duì)象,并維護(hù)了一個(gè)共享的引用計(jì)數(shù)器。

對(duì)于引用計(jì)數(shù)法實(shí)現(xiàn)的計(jì)數(shù),總是避免不了循環(huán)引用(或環(huán)形引用)的問(wèn)題,shared_ptr也不例外。

我們先來(lái)看看下面這個(gè)例子:

#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ù)結(jié)束,思考一下:spa和spb會(huì)釋放資源么?
}

上面代碼的輸出如下:

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

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

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

2、weak_ptr是什么?

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

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

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

3、weak_ptr如何使用?

接下來(lái),我們來(lái)看看weak_ptr的簡(jiǎn)單用法。

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

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

示例:

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

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

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

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

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

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

如果對(duì)象存在,lock()函數(shù)返回一個(gè)指向共享對(duì)象的shared_ptr,否則返回一個(gè)空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()這行的注釋去掉看看結(jié)果有什么不同。

除此之外,weak_ptr還提供了expired()函數(shù)來(lái)判斷所指對(duì)象是否已經(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(); // 此時(shí)sp被銷毀
 cout << wp.expired() << endl; // true表示已被銷毀,否則為false
}

代碼輸入如下:

A Constructor...
A Destructor...
1

3.3如何使用weak_ptr

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

最后,我們來(lái)看看如何使用weak_ptr來(lái)改造最前面的代碼,打破循環(huán)引用問(wè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ù)結(jié)束,思考一下:spa和spb會(huì)釋放資源么?
}

輸出結(jié)果如下:

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

從運(yùn)行結(jié)果可以看到spa和spb指向的對(duì)象都得到釋放!

總結(jié)

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

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲代碼

    C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲代碼

    大家好,本篇文章主要講的是C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲代碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • c++ map,mutimap刪除問(wèn)題分析

    c++ map,mutimap刪除問(wèn)題分析

    本文詳細(xì)介紹c++ map,mutimap刪除操作時(shí)的一些問(wèn)題,提供了解決方法,需要的朋友可以參考下
    2012-11-11
  • 深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn)

    深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn)

    這篇文章主要介紹了C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn),文中的示例對(duì)于鏈表結(jié)點(diǎn)的操作起到了很好的說(shuō)明作用,需要的朋友可以參考下
    2016-03-03
  • 淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)

    淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)

    下面小編就為大家?guī)?lái)一篇淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08
  • C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式

    C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式

    這篇文章主要介紹了C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的飛機(jī)大戰(zhàn)游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的飛機(jī)大戰(zhàn)游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的飛機(jī)大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++基于boost asio實(shí)現(xiàn)sync tcp server通信流程詳解

    C++基于boost asio實(shí)現(xiàn)sync tcp server通信流程詳解

    這篇文章主要介紹了C++基于boost asio實(shí)現(xiàn)sync tcp server通信的流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 老生常談c++中的靜態(tài)成員

    老生常談c++中的靜態(tài)成員

    有時(shí)候需要類的一些成員與類本身相關(guān)聯(lián),而不是與類的每個(gè)對(duì)象相關(guān)聯(lián)。比如類的所有對(duì)象都要共享的變量,這個(gè)時(shí)候我們就要用到類的靜態(tài)成員,今天通過(guò)實(shí)例代碼給大家詳細(xì)介紹,需要的朋友參考下吧
    2021-07-07
  • QT中窗口關(guān)閉自動(dòng)銷毀的實(shí)現(xiàn)示例

    QT中窗口關(guān)閉自動(dòng)銷毀的實(shí)現(xiàn)示例

    這篇文章主要介紹了QT中窗口關(guān)閉自動(dòng)銷毀,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C語(yǔ)言基于考研的棧和隊(duì)列

    C語(yǔ)言基于考研的棧和隊(duì)列

    這篇文章主要介紹了考研時(shí)的C語(yǔ)言中的堆棧和隊(duì)列的相關(guān)資料,需要的朋友可以參考下,小編覺(jué)得這篇文章寫的很好,希望能給你帶來(lái)幫助
    2021-08-08

最新評(píng)論