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

溫馨提示×

溫馨提示×

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

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

C++的智能指針使用實例分析

發布時間:2022-03-31 17:08:02 來源:億速云 閱讀:182 作者:iii 欄目:開發技術

今天小編給大家分享一下C++的智能指針使用實例分析的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    什么是RAII

    RAII(Resource Acquisition Is Initialization)是由C++之父提出的,中文翻譯為資源獲取即初始化,使用局部對象來管理資源的技術稱為資源獲取即初始化;這里的資源主要是指操作系統中有限的東西如內存(heap)、網絡套接字、互斥量、文件句柄等等,局部對象是指存儲在棧的對象,它的生命周期是由操作系統來管理的,無需人工介入

    RAII的原理

    資源的使用一般經歷三個步驟:

    • 獲取資源(創建對象)

    • 使用資源

    • 銷毀資源(析構對象)

    但是資源的銷毀往往是程序員經常忘記的一個環節,所以程序界就想如何在程序中讓資源自動銷毀呢?解決問題的方案就是:RAII,它充分的利用了C++語言局部對象自動銷毀的特性來控制資源的生命周期

    裸指針存在的問題

    1.難以區分指向的是單個對象還是一個數組

    2.使用完指針之后無法判斷是否應該銷毀指針,因為無法判斷指針是否”擁有“指向的對象

    3.在已經確定需要銷毀指針的情況下,也無法確定是用delete關鍵字刪除,還是有其他特殊的銷毀機制,例如通過將指針傳入某個特定的銷毀函數來摧毀指針

    4.即使已經確定了銷毀指針的方法,由于1的原因,仍然無法確定到底是i用delete(銷毀單個對象)還是delete[](銷毀一個數組)

    5.假設上述的問題都解決了,也很難保證在代碼的所有路徑中(分支結構,異常導致的挑戰),有且僅有一次銷毀指針的操作;任何一條路徑遺漏都可能導致內存的泄露,而銷毀多次則會導致未定義行為

    6.理論上沒有方法來分辨一個指針是否處于懸掛狀態

    auto_ptr

    class Object
    {
    	int value;
    public:
    	Object(int x = 0) :value(x)
    	{
    		cout << "Create Object:" << this << endl;
    	}
    	~Object()
    	{
    		cout << "Destory Object:" << this << endl;
    	}
    	int& Value()
    	{
    		return value;
    	}
    };
    
    template<class _Ty>
    class my_auto_ptr
    {
    private:
    	bool _Owns;
    	_Ty* _Ptr;
    public:
    	my_auto_ptr(_Ty* p = NULL) :_Owns(p != NULL), _Ptr(p)
    	{}
    	~my_auto_ptr()
    	{
    		if (_Owns)
    		{
    			delete _Ptr;
    		}
    		_Owns = false;
    		_Ptr = NULL;
    	}
    };
    
    void fun()
    {
    	my_auto_ptr<Object> obj(new Object(10));
    }
    
    int main()
    {
    	fun();
    }

    C++的智能指針使用實例分析

    C++的智能指針使用實例分析

    在這里將Object構建完成后,將其指針給到p,當函數結束去調動智能指針的析構函數去釋放空間

    若我們需要在fun()函數中,去調用Object類的方法obj->Value();

    class Object
    {
    	int value;
    public:
    	Object(int x = 0) :value(x)
    	{
    		cout << "Create Object:" << this << endl;
    	}
    	~Object()
    	{
    		cout << "Destory Object:" << this << endl;
    	}
    	int& Value()
    	{
    		return value;
    	}
    };
    
    template<class _Ty>
    class my_auto_ptr
    {
    private:
    	bool _Owns;
    	_Ty* _Ptr;
    public:
    	my_auto_ptr(_Ty* p = NULL) :_Owns(p != NULL), _Ptr(p)
    	{}
    	~my_auto_ptr()
    	{
    		if (_Owns)
    		{
    			delete _Ptr;
    		}
    		_Owns = false;
    		_Ptr = NULL;
    	}
    	_Ty* get()const
    	{
    		return _Ptr;
    	}
    	_Ty& operator*()const
    	{
    		return *(get());
    	}
    	_Ty* operator ->()const
    	{
    		return get();
    	}
    };
    
    void fun()
    {
    	my_auto_ptr<Object> obj(new Object(10));
    	cout << obj->Value() << endl;
    	cout << (*obj).Value() << endl;
    }
    
    int main()
    {
    	fun();
    }

    C++的智能指針使用實例分析

    通過運算符重載,(*obj) 后將直接指向堆區(heap)的對象實體

    若我們通過一個my_auto_ptr去創建另一個my_auto_ptr

    class Object
    {
    	int value;
    public:
    	Object(int x = 0) :value(x)
    	{
    		cout << "Create Object:" << this << endl;
    	}
    	~Object()
    	{
    		cout << "Destory Object:" << this << endl;
    	}
    	int& Value()
    	{
    		return value;
    	}
    };
    
    template<class _Ty>
    class my_auto_ptr
    {
    private:
    	bool _Owns;
    	_Ty* _Ptr;
    public:
    	my_auto_ptr(_Ty* p = NULL) :_Owns(p != NULL), _Ptr(p)
    	{}
    	~my_auto_ptr()
    	{
    		if (_Owns)
    		{
    			delete _Ptr;
    		}
    		_Owns = false;
    		_Ptr = NULL;
    	}
    	my_auto_ptr(const my_auto_ptr& obj):_Owns(obj._Owns),_Ptr(obj._ptr)
    	{	
    	}
    	my_auto_ptr& operator=(const my_auto_ptr& _Y)
    	{
    		if(this == &_Y) return *this;
    		if(_Owns)
    		{
    			delete _Ptr;
    		}
    		_Owns = _Y._Owns;
    		_Ptr = _Y._Ptr;
    		return 0;
    	}
    
    	_Ty* get()const
    	{
    		return _Ptr;
    	}
    	_Ty& operator*()const
    	{
    		return *(get());
    	}
    	_Ty* operator ->()const
    	{
    		return get();
    	}
    	void reset(_Ty* p = NULL)
    	{
    		if (_Owns)
    		{
    			delete _Ptr;
    		}
    		_Ptr = p;
    	}
    	_Ty* release()const
    	{
    		_Ty* tmp = NULL;
    		if (_Owns)
    		{
    			((my_auto_ptr*)this)->_Owns = false; //常性進行修改
    			tmp = _Ptr;
    			((my_auto_ptr*)this)->_Ptr = NULL;
    		}
    		return tmp;
    	}
    };
    
    void fun()
    {
    	my_auto_ptr<Object> pobja(new Object(10));
    	my_auto_ptr<Object> pobjb(pobja);
    }
    
    int main()
    {
    	fun();
    }

    如果通過淺拷貝,則兩個指針擁有同一個資源,在析構的過程會造成資源的重復釋放導致崩潰

    若設置為將其資源進行轉移

    my_auto_ptr(const my_auto_ptr& obj):_Owns(obj._Owns),_Ptr(release())
    {
    }
    my_auto_ptr& operator=(const my_auto_ptr& _Y)
    {
    	if(this == &_Y) return *this;
    	if(_Owns)
    	{
    		delete _Ptr;
    	}
    	_Owns = _Y._Owns;
    	_Ptr = _Y.release();
    	return 0;
    }
    void fun(my_auto_ptr<Object> apx)
    {
    	int x = apx->Value();
    	cout<<x<<endl;
    }
    int main()
    {
    	my_auto_ptr<Object> pobja(new Object(10));
    	fun(pobja);
    	int a = pobja->Value();
    	cout<<a<<endl;
    }

    那么上面的過程中,資源會進行轉移pobja將不再擁有資源,導致pobja失去資源進而程序崩潰

    這也就是auto_ptr的局限性,也導致該智能指針的幾乎沒有使用

    unique_ptr

    該智能指針屬于唯一性智能指針,將拷貝構造刪除,也就不能將其新建另一個對象,同時也不能作為參數傳入

    class Object
    {
    	int value;
    public:
    	Object(int x = 0) :value(x)
    	{
    		cout << "Create Object:" << this << endl;
    	}
    	~Object()
    	{
    		cout << "Destory Object:" << this << endl;
    	}
    	int& Value()
    	{
    		return value;
    	}
    };
    
    int main()
    {
    	std::unique_ptr<Object> pobja(new Object(10));
    	//std::unique_ptr<Object> pobjb(pobja); error
    	//不允許
    	std::unique_ptr<Object> pobjb(std::move(pobja));
    }

    通過移動賦值是可以的,通過明確的概念,對其資源進行轉移

    同時unique_ptr可以區分其所指向的是一個單獨空間,或者是連續的空間

    struct delete_ar_object
    {
    	void operator()(Object* op)
    	{
    		if(op == NULL) return;
    		delete[] op;
    	}
    }
    int main()
    {
    	std::unique_ptr<Object> pobja(new Object(10));
    	std::unique_ptr<Object,delete_ar_object> pobjb(new Object[10]);
    }

    在這里如果是連續空間,會調用刪除連續空間的刪除器;單獨空間則使用默認刪除器

    unique_ptr在編寫的時候,有多個模板類,分別對應單個對象的方案和一組對象的方案

    并且可以通過智能指針指向fopen打開的文件對象,而文件對象是同fclose去進行關閉的

    struct delete_file
    {
    	void operator()(FILE *fp)
    	{
    		if(fp == NULL) return;
    		fclose(fp);
    	}
    }
    std::unique_ptr<FILE,delete_file> pfile(fopen("zyq.txt","w"));

    這里只需要將默認的刪除器,更改為對文件對象的刪除器

    以上就是“C++的智能指針使用實例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

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

    c++
    AI

    民和| 汝南县| 肇源县| 西畴县| 芒康县| 朝阳县| 林州市| 巴彦淖尔市| 锦屏县| 始兴县| 瑞安市| 北宁市| 武乡县| 噶尔县| 武陟县| 石家庄市| 桂林市| 崇文区| 元谋县| 灵武市| 龙海市| 托克托县| 眉山市| 江孜县| 金湖县| 九江市| 连城县| 贵阳市| 治县。| 始兴县| 宿迁市| 宁海县| 根河市| 四川省| 临泉县| 定州市| 禄丰县| 鹤峰县| 北京市| 通海县| 正阳县|