一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

c 11新特性之智能指針

 西北望msm66g9f 2020-12-04

很多人談到c++,說它特別難,可能有一部分就是因?yàn)閏++的內(nèi)存管理吧,不像java那樣有虛擬機(jī)動(dòng)態(tài)的管理內(nèi)存,在程序運(yùn)行過程中可能就會(huì)出現(xiàn)內(nèi)存泄漏,然而這種問題其實(shí)都可以通過c++11引入的智能指針來(lái)解決,相反我還認(rèn)為這種內(nèi)存管理還是c++語(yǔ)言的優(yōu)勢(shì),因?yàn)楸M在掌握。

c++11引入了三種智能指針:

  • std::shared_ptr

  • std::weak_ptr

  • std::unique_ptr

shared_ptr

shared_ptr使用了引用計(jì)數(shù),每一個(gè)shared_ptr的拷貝都指向相同的內(nèi)存,每次拷貝都會(huì)觸發(fā)引用計(jì)數(shù)+1,每次生命周期結(jié)束析構(gòu)的時(shí)候引用計(jì)數(shù)-1,在最后一個(gè)shared_ptr析構(gòu)的時(shí)候,內(nèi)存才會(huì)釋放。

使用方法如下:

struct ClassWrapper { ClassWrapper() {        cout << 'construct' << endl; data = new int[10]; }    ~ClassWrapper() { cout << 'deconstruct' << endl; if (data != nullptr) { delete[] data; } } void Print() { cout << 'print' << endl; } int* data;};
void Func(std::shared_ptr<ClassWrapper> ptr) {    ptr->Print();}
int main() { auto smart_ptr = std::make_shared<ClassWrapper>(); auto ptr2 = smart_ptr; // 引用計(jì)數(shù)+1 ptr2->Print(); Func(smart_ptr); // 引用計(jì)數(shù)+1 smart_ptr->Print(); ClassWrapper *p = smart_ptr.get(); // 可以通過get獲取裸指針 p->Print(); return 0;}

智能指針還可以自定義刪除器,在引用計(jì)數(shù)為0的時(shí)候自動(dòng)調(diào)用刪除器來(lái)釋放對(duì)象的內(nèi)存,代碼如下:

std::shared_ptr<int> ptr(new int, [](int *p){ delete p; });

關(guān)于shared_ptr有幾點(diǎn)需要注意:

· 不要用一個(gè)裸指針初始化多個(gè)shared_ptr,會(huì)出現(xiàn)double_free導(dǎo)致程序崩潰

· 通過shared_from_this()返回this指針,不要把this指針作為shared_ptr返回出來(lái),因?yàn)閠his指針本質(zhì)就是裸指針,通過this返回可能 會(huì)導(dǎo)致重復(fù)析構(gòu),不能把this指針交給智能指針管理。

class A { shared_ptr<A> GetSelf() { return shared_from_this(); // return shared_ptr<A>(this); 錯(cuò)誤,會(huì)導(dǎo)致double free } };
  • 盡量使用make_shared,少用new。

  • 不要delete get()返回來(lái)的裸指針。

  • 不是new出來(lái)的空間要自定義刪除器。

  • 要避免循環(huán)引用,循環(huán)引用導(dǎo)致內(nèi)存永遠(yuǎn)不會(huì)被釋放,造成內(nèi)存泄漏。

using namespace std;struct A;struct B;
struct A { std::shared_ptr<B> bptr; ~A() { cout << 'A delete' << endl; }};
struct B { std::shared_ptr<A> aptr; ~B() { cout << 'B delete' << endl; }};
int main() { auto aaptr = std::make_shared<A>(); auto bbptr = std::make_shared<B>(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; return 0;}

上面代碼,產(chǎn)生了循環(huán)引用,導(dǎo)致aptr和bptr的引用計(jì)數(shù)為2,離開作用域后aptr和bptr的引用計(jì)數(shù)-1,但是永遠(yuǎn)不會(huì)為0,導(dǎo)致指針永遠(yuǎn)不會(huì)析構(gòu),產(chǎn)生了內(nèi)存泄漏,如何解決這種問題呢,答案是使用weak_ptr。

weak_ptr

weak_ptr是用來(lái)監(jiān)視shared_ptr的生命周期,它不管理shared_ptr內(nèi)部的指針,它的拷貝的析構(gòu)都不會(huì)影響引用計(jì)數(shù),純粹是作為一個(gè)旁觀者監(jiān)視shared_ptr中管理的資源是否存在,可以用來(lái)返回this指針和解決循環(huán)引用問題。

  • 作用1:返回this指針,上面介紹的shared_from_this()其實(shí)就是通過weak_ptr返回的this指針,這里參考我之前寫的源碼分析shared_ptr實(shí)現(xiàn)的文章,最后附上鏈接。

  • 作用2:解決循環(huán)引用問題。

struct A;struct B;
struct A { std::shared_ptr<B> bptr; ~A() { cout << 'A delete' << endl; } void Print() { cout << 'A' << endl; }};
struct B { std::weak_ptr<A> aptr; // 這里改成weak_ptr ~B() { cout << 'B delete' << endl; } void PrintA() { if (!aptr.expired()) { // 監(jiān)視shared_ptr的生命周期 auto ptr = aptr.lock(); ptr->Print(); } }};
int main() { auto aaptr = std::make_shared<A>(); auto bbptr = std::make_shared<B>(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; bbptr->PrintA(); return 0;}輸出:AA deleteB delete

unique_ptr

std::unique_ptr是一個(gè)獨(dú)占型的智能指針,它不允許其它智能指針共享其內(nèi)部指針,也不允許unique_ptr的拷貝和賦值。使用方法和shared_ptr類似,區(qū)別是不可以拷貝:

using namespace std;
struct A { ~A() { cout << 'A delete' << endl; } void Print() { cout << 'A' << endl; }};

int main() { auto ptr = std::unique_ptr<A>(new A); auto tptr = std::make_unique<A>(); // error, c++11還不行,需要c++14 std::unique_ptr<A> tem = ptr; // error, unique_ptr不允許移動(dòng) ptr->Print(); return 0;}

unique_ptr也可以像shared_ptr一樣自定義刪除器,使用方法和shared_ptr相同。

關(guān)于c++11的智能指針的使用就介紹到這里,大家有問題可以點(diǎn)此留言 ,我會(huì)盡快回復(fù)~

參考資料

https://www.jianshu.com/p/b6ac02d406a0
https:///post/5dcaa857e51d457f7675360b#heading-16
《深入應(yīng)用c++11:代碼優(yōu)化與工程級(jí)應(yīng)用》

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲国产精品久久综合网| 又大又紧又硬又湿又爽又猛| 国产成人精品一区二三区在线观看 | 久久福利视频在线观看| 99久久国产精品亚洲| 午夜福利激情性生活免费视频| 手机在线不卡国产视频| 国产二级一级内射视频播放| 日韩亚洲激情在线观看| 欧美日韩国产成人高潮| 蜜桃av人妻精品一区二区三区| 国产免费操美女逼视频| 91人妻人人做人碰人人九色| 嫩呦国产一区二区三区av| 成人亚洲国产精品一区不卡| 三级高清有码在线观看| 亚洲天堂国产精品久久精品| 欧美精品久久男人的天堂| 熟女一区二区三区国产| 日韩aa一区二区三区| 婷婷开心五月亚洲综合| 日本人妻熟女一区二区三区| 午夜福利直播在线视频| 国产日韩欧美专区一区| 日韩一区二区三区久久| 欧美日韩国产一级91| 亚洲综合香蕉在线视频| 久久99国产精品果冻传媒| 国产丝袜美女诱惑一区二区| 国产福利在线播放麻豆| 激情内射亚洲一区二区三区| 国产又粗又硬又长又爽的剧情| 亚洲欧美日韩在线中文字幕| 午夜精品成年人免费视频| 98精品永久免费视频| 91欧美亚洲视频在线| 国产中文字幕一二三区| 91亚洲精品综合久久| 麻豆tv传媒在线观看| 国产福利在线播放麻豆| 丰满人妻一二三区av|