shared_ptr循環(huán)引用&定置刪除器

shared_ptr雖然方便,但是它有著一個(gè)致命的缺陷就是循環(huán)引用問題,因?yàn)閟hared_ptr本身并沒有能力解決這個(gè)問題,所以我們又引入了弱指針weak_ptr來輔助shared_ptr解決這個(gè)問題。

十多年的陜州網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整陜州建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“陜州網(wǎng)站設(shè)計(jì)”,“陜州網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

那么循環(huán)引用又是什么場景?

舉個(gè)栗子:

假設(shè)現(xiàn)在我們要?jiǎng)?chuàng)建一個(gè)雙向×××鏈表,但是這個(gè)鏈表的指針域全部都用shared_ptr維護(hù):

struct Node

{

    int _data;

    shared_ptr<Node> _next;

    shared_ptr<Node> _prev;

}

假設(shè)現(xiàn)在先創(chuàng)建兩個(gè)結(jié)點(diǎn),并用shared_ptr維護(hù)這兩個(gè)結(jié)點(diǎn):

shared_ptr<Node> sp1(new Node);

shared_ptr<Node> sp2(new Node);

現(xiàn)在將這兩個(gè)指針互相連接:

sp1->_next=sp2;

sp2->prev=sp1;

shared_ptr循環(huán)引用&定置刪除器

shared_ptr循環(huán)引用&定置刪除器

   為了解決循化引用問題,我們又引入了weak_ptr弱指針,用來輔助shared_ptr。注意weak_ptr不能單獨(dú)使用,必須輔助shared_ptr才能使用。weak_ptr是一種不控制所指向?qū)ο笊嬷芷诘闹悄苤羔?,它指向一個(gè)由shared_ptr管理的對(duì)象,將一個(gè)weak_ptr綁定到一個(gè)shared_ptr不會(huì)改變shared_ptr的引用計(jì)數(shù)。一但最后一個(gè)指向?qū)ο蟮膕hared_ptr被銷毀,對(duì)象就會(huì)被銷毀,即使有weak_ptr指向?qū)ο?,?duì)象還是會(huì)被釋放。

例:

所以為了解決上面栗子中的循環(huán)引用問題,我們可以將指針域的智能指針聲明為弱指針。

struct Node

{

    int _data;

    weak_ptr<Node> _next;

    weak_ptr<Node> _prev;

}

二、定置刪除器

   一般情況下,我們都用智能指針是用來管理動(dòng)態(tài)內(nèi)存的,其實(shí)智能指針是用來管理資源的,資源很多,動(dòng)態(tài)內(nèi)存只是資源的一種,比如說我們可以用智能指針來管理文件,那么我們就不能用智能指針默認(rèn)的刪除器了,因?yàn)橐芾砦募脑捵詈笫莊close,而不是delete,所以我們就必須自己定制一個(gè)刪除器。

例:以管理文件為例,實(shí)現(xiàn)定置刪除器。

要實(shí)現(xiàn)定置刪除器,就要用到仿函數(shù):仿函數(shù)就是將"()"重載。

//定置刪除器的仿函數(shù)
struct Fclose
{
       void operator()(void *ptr)
       {
              fclose((FILE *)ptr);
              cout << "fclose()" << endl;
       }
};
void test()
{
       boost::shared_ptr<FILE> sp(fopen("test.txt","w"),Fclose());    //調(diào)用構(gòu)造函數(shù)構(gòu)造一個(gè)匿名對(duì)象傳遞過去,文件正常關(guān)閉
}

再舉一個(gè)栗子:
用智能指針管理malloc開辟的動(dòng)態(tài)內(nèi)存,那么我們?cè)卺尫诺臅r(shí)候就要用free釋放:
//定置刪除器的仿函數(shù)
struct Free
{
       void operator()(void *ptr)
       {
              free(ptr);
       }
};
void test()
{
       boost::shared_ptr<int> sp((int *)malloc(sizeof(int)),Free());        //能夠正確的釋放空間
}


三、簡單的實(shí)現(xiàn)一個(gè)有定置刪除器的shared_ptr

struct Fclose
{
	void operator()(void *ptr)
	{
		fclose((FILE *)ptr);
		cout << "fclose()" << endl;
	}
};

struct Free
{
	void operator()(void *ptr)
	{
		free(ptr);
		cout << "free()" <<endl;
	}
};


//默認(rèn)刪除器是delete
struct DefaultDel
{
	void operator()(void* ptr)
	{
		delete ptr;
		cout << "delete ptr" << endl;
	}
};


template<typename T, typename D = DefaultDel>
class SharedPtr            //采用引用計(jì)數(shù),實(shí)現(xiàn)一個(gè)可以有多個(gè)指針指向同一塊內(nèi)存的類模板,SharedPtr是類模板,不是智能指針類型
{
public:
	SharedPtr(T* ptr, D del = DefaultDel());
	SharedPtr(const SharedPtr<T,D>& sp);
	SharedPtr<T,D>& operator=(SharedPtr<T,D> sp);
	T& operator*();
	T* operator->();
	~SharedPtr();
	int Count()
	{
		return *_pCount;
	}
private:
	void Release()
	{
		if (--(*_pCount) == 0)
		{
			_del(_ptr);
 			delete _pCount;
			_ptr = NULL;
			_pCount = NULL;
		}
	}
private:
	T* _ptr;
	int* _pCount;
	D _del;
};


template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::SharedPtr(T* ptr,D del)
:_ptr(ptr)
, _pCount(new int(1))
,_del(del){}

template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::SharedPtr(const SharedPtr<T,D>& sp)
{
	_ptr = sp._ptr;
	_pCount= sp._pCount;
	++(*_pCount);
}

template<typename T, typename D = DefaultDel>
SharedPtr<T,D>& SharedPtr<T,D>::operator=(SharedPtr<T,D> sp)
{
	std::swap(sp._ptr,_ptr);
	std::swap(sp._pCount,_pCount);
	return *this;
}

template<typename T, typename D = DefaultDel>
T& SharedPtr<T,D>::operator*()
{
	return *_ptr;
}

template<typename T, typename D = DefaultDel>
T* SharedPtr<T,D>::operator->()
{
	return _ptr;
}

template<typename T, typename D = DefaultDel>
SharedPtr<T,D>::~SharedPtr()
{
	Release();
}



//測試用例
void test()
{
	SharedPtr<int> sp(new int(1));
	SharedPtr<FILE,Fclose> sp1(fopen("test.txt","w"),Fclose());
	SharedPtr<string,Free> sp3((string *)malloc(sizeof(string)),Free());
}


int main()
{
	test();
	system("pause");
	return 0;
}

文章名稱:shared_ptr循環(huán)引用&定置刪除器
轉(zhuǎn)載來于:http://muchs.cn/article16/ighedg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)Google、建站公司、、營銷型網(wǎng)站建設(shè)標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)