日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > C語言與CPP編程
[導(dǎo)讀]很多人談到c++,說它特別難,可能有一部分就是因?yàn)閏++的內(nèi)存管理吧,不像java那樣有虛擬機(jī)動態(tài)的管理內(nèi)存,在程序運(yùn)行過程中可能就會出現(xiàn)內(nèi)存泄漏,然而這種問題其實(shí)都可以通過c++11引入的智能指針來解決,相反我還認(rèn)為這種內(nèi)存管理還是c++語言的優(yōu)勢,因?yàn)楸M

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

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

  • std::shared_ptr

  • std::weak_ptr

  • std::unique_ptr

shared_ptr

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

使用方法如下:

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; // 引用計數(shù)+1 ptr2->Print(); Func(smart_ptr); // 引用計數(shù)+1 smart_ptr->Print(); ClassWrapper *p = smart_ptr.get(); // 可以通過get獲取裸指針 p->Print(); return 0;}

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

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

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

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

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

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

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

  • 不是new出來的空間要自定義刪除器。

  • 要避免循環(huán)引用,循環(huán)引用導(dǎo)致內(nèi)存永遠(yuǎn)不會被釋放,造成內(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的引用計數(shù)為2,離開作用域后aptr和bptr的引用計數(shù)-1,但是永遠(yuǎn)不會為0,導(dǎo)致指針永遠(yuǎn)不會析構(gòu),產(chǎn)生了內(nèi)存泄漏,如何解決這種問題呢,答案是使用weak_ptr。

weak_ptr

weak_ptr是用來監(jiān)視shared_ptr的生命周期,它不管理shared_ptr內(nèi)部的指針,它的拷貝的析構(gòu)都不會影響引用計數(shù),純粹是作為一個旁觀者監(jiān)視shared_ptr中管理的資源是否存在,可以用來返回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是一個獨(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不允許移動 ptr->Print(); return 0;}

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

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

參考資料

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

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉