91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

智能指針的簡單剖析和實現

發布時間:2020-06-29 02:06:16 來源:網絡 閱讀:362 作者:檸公子 欄目:編程語言

在C語言中我們用指針來進行內存管理,這也是C語言的強大之處。然而,也正是指針的存在使得C語言變得令人懊惱,內存泄漏、垂懸指針等等問題。強大的C++則采用智能指針(Smart_Ptr)來處理這個問題.

好了,什么是智能指針呢?智能指針的行為類似常規指針,重要的區別是它負責自動釋放所指向的對象。這樣以防止內存泄漏。

智能指針都有哪些種類呢?

智能指針的簡單剖析和實現

通過上述表格可以看出有如此多的智能指針,C11標準庫已經引進unique_ptr/shared_ptr/weak_ptr供我們使用。

下面來簡單談談這些指針的原理和實現。

First——>auto ptr

auto ptr的實現原理主要是管理權的轉移。它是所擁有的對象的唯一擁有者,也就是一個對象只有一個擁有者。

代碼實現:

template <class T>
class AutoPtr
{
public:
	AutoPtr(T* Ptr)
		:_Ptr(Ptr)
	{}

	~AutoPtr()
	{
		if(_Ptr!=NULL)
		{
			delete _Ptr;
		}
	}

	AutoPtr(AutoPtr<T>& ap)
	{
		_Ptr=ap._Ptr;
		ap._Ptr=NULL;
	}

	AutoPtr<T> operator=(AutoPtr<T>& ap)
	{
		if(&ap!=this)
		{
			delete _Ptr;
			_Ptr=ap._Ptr;
			ap._Ptr=NULL;
		}
		return *this;
	}

	T& operator*()
	{
		return *_Ptr;
	}

	T* operator->()
	{
		return _Ptr;
	}
private:
	T* _Ptr;
};

通過代碼我們可以看出由于auto ptr指針唯一性,即一個對象只能有一個auto ptr指針所指向它。因此,當auto ptr以傳值方式被作為參數傳遞給某函數時,這時對象的原來擁有者就放棄了對象的擁有權,把它轉移到被調用函數中的參數上,如果函數不再將擁有權傳遞出去,由于形參的作用域僅僅為函數內部,當函數退出時,它所指向的對象將被銷毀。當函數返回一個auto ptr時,其擁有權又被轉移到了調用端。因此,我們盡量不要使用auto ptr傳參,或者引用傳遞。此外,auto ptr 還不能作為容器的成員,C++標準明確禁止這樣做。

Second——>scoped ptr

scoped ptr與auto ptr類似,它實現的原理則是防拷貝,也就是它不能轉移管理權,所以不能被賦值或者拷貝構造。那么,我們可以將拷貝構造和賦值運算符重載函數只聲明不實現,并將其聲明為保護,那么也就防止了別人在類外實現它。

代碼實現:

template <class T>
class ScopedPtr
{
public:
	ScopedPtr(T* Ptr)
		:_Ptr(Ptr)
	{}

	~ScopedPtr()
	{
		if(_Ptr!=NULL)
		{
			delete _Ptr;
		}
	}

	T& operator*()
	{
		return *_Ptr;
	}

	T* operator->()
	{
		return _Ptr;
	}
protected:
	T* _Ptr;
	ScopedPtr(ScopedPtr<T>& sp);
	ScopedPtr<T>& operator=(ScopedPtr<T>& sp);
};

通過代碼可以看出scoped ptr 的實現十分的簡單粗暴,動態分配對象的生命周期限制在特定的作用域,采用scoped ptr可以有作用域保護,使用起來也優于auto ptr。

Third——>shared ptr

shared ptr顧名思義就是共享,所以也就是說多個指針可以指向同一個內存,它所采用的是引用計數的原理,也就是引進了一個計數器shared_count,用來表示當前有多少個智能指針對象共享指針指向的內存。因此shared_ptr可以做為STL容器的元素。析構函數中不是直接釋放指針對應的內塊,shared_count大于1則不釋放內存只是將引用計數減1,只是計數等于1時釋放內存。這樣避免了一塊內存被多次析構的問題。

代碼實現:

template <class T>
class SharedPtr
{
public:
	SharedPtr(T* Ptr)
		:_Ptr(Ptr)
		,_Pcount(new long(1))
	{}

	~SharedPtr()
	{
		_Release();
	}

	SharedPtr(SharedPtr<T>& sp)
		:_Ptr(sp._Ptr)
		,_Pcount(sp._Pcount)
	{
		++(*_Pcount);
	}

	SharedPtr<T>& operator=(SharedPtr<T>& sp)
	{
		if(&sp!=this)
		{
			_Release();
		    _Ptr=sp._Ptr;
		    _Pcount=sp._Pcount;
		    ++(*_Pcount);
		}	
	}

	T& operator*()
	{
		return *_Ptr;
	}

	T* operator->()
	{
		return _Ptr;
	}

	long UseCount()
	{
		return *_Pcount;
	}

	T* GetPtr()
	{
		return _Ptr;
	}

protected:
	T* _Ptr;
	long *_Pcount;
	void _Release()
	{
		if(--(*_Pcount)==0)
			{
				delete _Ptr;
				delete _Pcount;
			}
	}
};

由上述代碼可知,我們在拷貝和賦值也會將引用計數進行遞增,而實現也只是一般的復制。

動態對象的正確釋放是編程中最容易出錯的地方,利用智能指針可以更安全的使用動態對象,使得我們的程序更高效、安全。

向AI問一下細節

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

AI

咸丰县| 平昌县| 宁安市| 淮滨县| 巴南区| 永修县| 安新县| 广西| 张掖市| 尖扎县| 攀枝花市| 宣汉县| 龙南县| 黎平县| 渭源县| 林州市| 民勤县| 黔西| 沭阳县| 玉树县| 吴堡县| 乌恰县| 青龙| 安塞县| 海原县| 阜新| 上思县| 新龙县| 五指山市| 仲巴县| 石嘴山市| 澄城县| 平远县| 云霄县| 中阳县| 新源县| 进贤县| 昂仁县| 舒城县| 宕昌县| 金湖县|