亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

shared_ptr循環引用&定置刪除器

發布時間:2020-08-01 13:54:19 來源:網絡 閱讀:1143 作者:我是你帆哥 欄目:編程語言

shared_ptr雖然方便,但是它有著一個致命的缺陷就是循環引用問題,因為shared_ptr本身并沒有能力解決這個問題,所以我們又引入了弱指針weak_ptr來輔助shared_ptr解決這個問題。


那么循環引用又是什么場景?

舉個栗子:

假設現在我們要創建一個雙向×××鏈表,但是這個鏈表的指針域全部都用shared_ptr維護:

struct Node

{

    int _data;

    shared_ptr<Node> _next;

    shared_ptr<Node> _prev;

}


假設現在先創建兩個結點,并用shared_ptr維護這兩個結點:

shared_ptr<Node> sp1(new Node);

shared_ptr<Node> sp2(new Node);


現在將這兩個指針互相連接:

sp1->_next=sp2;

sp2->prev=sp1;

shared_ptr循環引用&定置刪除器


shared_ptr循環引用&定置刪除器


   為了解決循化引用問題,我們又引入了weak_ptr弱指針,用來輔助shared_ptr。注意weak_ptr不能單獨使用,必須輔助shared_ptr才能使用。weak_ptr是一種不控制所指向對象生存周期的智能指針,它指向一個由shared_ptr管理的對象,將一個weak_ptr綁定到一個shared_ptr不會改變shared_ptr的引用計數。一但最后一個指向對象的shared_ptr被銷毀,對象就會被銷毀,即使有weak_ptr指向對象,對象還是會被釋放。


例:

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

struct Node

{

    int _data;

    weak_ptr<Node> _next;

    weak_ptr<Node> _prev;

}


二、定置刪除器

   一般情況下,我們都用智能指針是用來管理動態內存的,其實智能指針是用來管理資源的,資源很多,動態內存只是資源的一種,比如說我們可以用智能指針來管理文件,那么我們就不能用智能指針默認的刪除器了,因為要管理文件的話最后是fclose,而不是delete,所以我們就必須自己定制一個刪除器。


例:以管理文件為例,實現定置刪除器。

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

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

再舉一個栗子:
用智能指針管理malloc開辟的動態內存,那么我們在釋放的時候就要用free釋放:
//定置刪除器的仿函數
struct Free
{
       void operator()(void *ptr)
       {
              free(ptr);
       }
};
void test()
{
       boost::shared_ptr<int> sp((int *)malloc(sizeof(int)),Free());        //能夠正確的釋放空間
}




三、簡單的實現一個有定置刪除器的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;
	}
};


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


template<typename T, typename D = DefaultDel>
class SharedPtr            //采用引用計數,實現一個可以有多個指針指向同一塊內存的類模板,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;
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新乐市| 张家口市| 普兰店市| 腾冲县| 岚皋县| 吉木萨尔县| 加查县| 文化| 双江| 郧西县| 繁昌县| 乌兰察布市| 彭水| 冷水江市| 正镶白旗| 岐山县| 新民市| 阳山县| 和林格尔县| 岑溪市| 谢通门县| 赤城县| 锡林郭勒盟| 广元市| 纳雍县| 邮箱| 铁岭县| 阿拉善右旗| 沁阳市| 周宁县| 六安市| 文安县| 和田县| 鹤庆县| 康定县| 安龙县| 天台县| 离岛区| 浦县| 搜索| 方城县|