欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:C++RAII內(nèi)存管理技術(shù)

柚子快報激活碼778899分享:C++RAII內(nèi)存管理技術(shù)

http://yzkb.51969.com/

文章目錄

一.什么是RAII內(nèi)存管理技術(shù)?二.智能指針unique_ptrshared_ptr循環(huán)引用問題weak_ptr

一.什么是RAII內(nèi)存管理技術(shù)?

C++在引入異常機制后,代碼執(zhí)行流的跳轉(zhuǎn)變得難以預(yù)料,如果使用普通的指針進行內(nèi)存管理,很難避免內(nèi)存泄漏的問題(執(zhí)行流跳轉(zhuǎn)導致堆區(qū)資源無法被釋放)RAII技術(shù)指的是利用對象的生命周期來管理內(nèi)存資源,就堆區(qū)內(nèi)存資源的管理而言,指的就是:將指針封裝在類中,在類對象構(gòu)造時獲取堆區(qū)資源,當類對象生命周期結(jié)束時,通過類對象的析構(gòu)函數(shù)自動完成堆區(qū)資源的釋放,這樣的類對象就是智能指針

智能指針可以有效地避免開發(fā)中出現(xiàn)內(nèi)存泄漏的問題,同時為開發(fā)者省去了很多時間和精力

二.智能指針

C++11標準庫中智能指針主要分為三大類:

unique_ptr

unique_ptr對象之間不允許進行拷貝,即一個unique_ptr對象管理一塊堆區(qū)內(nèi)存資源,是一一對應(yīng)的關(guān)系unique_ptr的簡單實現(xiàn)原理:

//不允許拷貝的智能指針

//delfunc是堆區(qū)資源釋放函數(shù),用于調(diào)用delete或者delete[]

template

class unique_ptr

{

public:

unique_ptr(T * ptr = nullptr)

:_ptr(ptr)

{}

~unique_ptr()

{

if (_ptr)

{

delfunc del;

del(_ptr);

std::cout << "delete" << std::endl;

}

}

//讓智能指針可以像指針一樣被使用

T& operator*()

{

return *_ptr;

}

T* operator->()

{

return _ptr;

}

//禁止unique_ptr對象間的拷貝

unique_ptr(const unique_ptr& unptr) = delete;

unique_ptr& operator=(const unique_ptr& unptr) = delete;

private:

T* _ptr;

};

使用指針管理堆區(qū)資源時,我們會讓其指向單個對象或者對象數(shù)組,單個對象用delete完成資源釋放,而對象數(shù)組要采用delete[]完成資源釋放.unique_ptr的類模板參數(shù)delfunc的設(shè)計目的就是為了區(qū)分上述兩種情況,讓使用者通過設(shè)計仿函數(shù)的方式在delete和delete[]之間做選擇

shared_ptr

shared_ptr是允許進行拷貝的智能指針,然而shared_ptr對象之間發(fā)生拷貝時,就會出現(xiàn)多個智能指針對象同時管理同一塊堆區(qū)內(nèi)存的情況,shared_ptr通過引用計數(shù)的技術(shù)避免了同一塊堆區(qū)資源被釋放多次的情況出現(xiàn):引用計數(shù)的實現(xiàn)思路:

在shared_ptr內(nèi)部封裝一個指針int * recount用來維護引用計數(shù)變量每當一個shared_ptr對象進行構(gòu)造并申請堆區(qū)資源時,同時在堆區(qū)申請一個int變量作為該shared_ptr對象所指向的堆區(qū)資源的引用計數(shù)變量每當shared_ptr被拷貝時,連同int * recount一起拷貝,然后讓引用計數(shù)變量加一即可(賦值重載的實現(xiàn)還要考慮引用計數(shù)變量減一和堆區(qū)資源釋放的問題)每當shared_ptr析構(gòu)時,引用計數(shù)變量減一,若引用計數(shù)變量減為0,則釋放堆區(qū)資源 shared_ptr的簡單實現(xiàn)原理:

//允許拷貝的智能指針,利用引用計數(shù)解決內(nèi)存管理沖突

//delfunc是堆區(qū)資源釋放函數(shù),用于調(diào)用delete或者delete[]

template

class shared_ptr

{

public:

//構(gòu)造智能指針(同時創(chuàng)建引用計數(shù)變量)

shared_ptr(T* ptr = nullptr)

:_ptr(ptr),

_recount(new int(1))

{}

shared_ptr(const shared_ptr& shptr)

: _ptr(shptr._ptr),

_recount(shptr._recount)

{

//智能指針拷貝增加引用計數(shù)

(*_recount)++;

}

shared_ptr& operator=(const shared_ptr& shptr)

{

if (_ptr != shptr._ptr)

{

//智能指針指向改變,其先前指向的堆區(qū)內(nèi)存和引用計數(shù)變量需要處理

Release();

//完成智能指針拷貝并增加引用計數(shù)

_ptr = shptr._ptr;

_recount = shptr._recount;

++(*_recount);

}

return (*this);

}

~shared_ptr()

{

Release();

}

//讓智能指針可以像指針一樣被使用

T& operator*()

{

return *_ptr;

}

T* operator->()

{

return _ptr;

}

T* getptr() const

{

return _ptr;

}

private:

//將資源釋放函數(shù)進行封裝,方便復用

//引用計數(shù)減一,若引用計數(shù)減為0則釋放資源

void Release()

{

//引用計數(shù)減一

--(*_recount);

//引用計數(shù)為0則釋放資源

if (*_recount == 0)

{

if (_ptr)

{

delfunc del;

del(_ptr);

std::cout << "delete" << std::endl;

}

//同時注意釋放引用計數(shù)變量

delete _recount;

}

}

private:

T* _ptr;

int* _recount;

};

shared_ptr類內(nèi)部同時還要解決引用計數(shù)變量帶來的線程安全的問題,這里暫不討論

循環(huán)引用問題

shared_ptr用在自引用結(jié)構(gòu)體中會出現(xiàn)對象無法析構(gòu)的問題:

template

class deletefunc

{

public:

void operator()(T* ptr)

{

delete ptr;

}

};

// 循環(huán)引用

struct ListNode

{

int _val;

shared_ptr> _next;

shared_ptr> _prev;

~ListNode()

{

cout << "~ListNode()" << endl;

}

};

// 循環(huán)引用

void test_shared_cycle()

{

share_ptr> n1(new ListNode);

share_ptr> n2(new ListNode);

n1->_next = n2;

n2->_prev = n1;

}

當test_shared_cycle()函數(shù)執(zhí)行完后,兩個鏈表節(jié)點都無法正常析構(gòu),shared_ptr引發(fā)了循環(huán)引用的問題:n1節(jié)點的析構(gòu)依賴于n2節(jié)點中_prev指針的析構(gòu),n2節(jié)點中_prev指針的析構(gòu)依賴于n2節(jié)點的析構(gòu),n2節(jié)點的析構(gòu)又依賴于n1節(jié)點中_next指針的析構(gòu), n1節(jié)點中_next指針的析構(gòu)又依賴于n1節(jié)點的析構(gòu).如此往復構(gòu)成了循環(huán)的依賴關(guān)系導致兩個節(jié)點都無法被釋放.weak_ptr就是為了解決循環(huán)引用問題而設(shè)計的

weak_ptr

weak_ptr智能指針不參與堆區(qū)內(nèi)存的申請和釋放,也不會增加特定內(nèi)存塊的引用計數(shù)(其功能和普通指針差不多),weak_ptr支持以shared_ptr為引用形參的拷貝構(gòu)造和賦值weak_ptr簡單實現(xiàn)原理:

//用于配合share_ptr的使用用于循環(huán)引用的場景

//delfunc是堆區(qū)資源釋放函數(shù),用于調(diào)用delete或者delete[]

//weak_ptr不參與資源的申請和釋放

template

class weak_ptr

{

public:

weak_ptr()

:_ptr(nullptr)

{}

~weak_ptr()

{}

weak_ptr(const weak_ptr& wptr)

:_ptr(wptr._ptr)

{}

weak_ptr(const share_ptr& shptr)

:_ptr(shptr.getptr())

{}

weak_ptr& operator=(const weak_ptr& wptr)

{

_ptr = wptr._ptr;

return (*this);

}

weak_ptr& operator=(const share_ptr& shptr)

{

_ptr = shptr.getptr();

return (*this);

}

//讓智能指針可以像指針一樣被使用

T& operator*()

{

return *_ptr;

}

T* operator->()

{

return _ptr;

}

private:

T* _ptr;

};

在自引用結(jié)構(gòu)體中采用weak_ptr就可以避免出現(xiàn)循環(huán)引用的問題

柚子快報激活碼778899分享:C++RAII內(nèi)存管理技術(shù)

http://yzkb.51969.com/

好文推薦

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19268159.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄