一、實驗目的
●熟悉智能指針
●對智能指針進行設計和實現
二、實驗實驗環境: 在windows系統下用c++編寫
三、實驗內容
1. 對智能指針進行設計
2. 對智能指針進行實現
四、實驗前的分析
由於 C++ 語言沒有自動內存回收機制,程序員每次 new 出來的內存都要手動 delete。程序員忘記 delete,流程太複雜,最終導致沒有 delete,異常導致程序過早退出,沒有執行 delete 的情況並不罕見。對於編譯器來說,智能指針實際上是一個棧對象,並非指針類型,在棧對象生命期即將結束時,智能指針通過析構函數釋放有它管理的堆內存。所有智能指針都重載了“operator->”操作符,直接返回對象的引用,用以操作對象。訪問智能指針原來的方法則使用“.”操作符。 訪問智能指針包含的裸指針則可以用 get() 函數。由於智能指針是一個對象,所以if (my_smart_object)永遠爲真,要判斷智能指針的裸指針是否爲空,需要這樣判斷:if (my_smart_object.get())。智能指針包含了 reset() 方法,如果不傳遞參數(或者傳遞 NULL),則智能指針會釋放當前管理的內存。如果傳遞一個對象,則智能指針會釋放當前對象,來管理新傳入的對象。 智能指針(smart pointer)是存儲指向動態分配(堆)對象指針的類,用於生存期控制,能夠確保自動正確的銷燬動態分配的對象,防止內存泄露。它的一種通用實現技術是使用引用計數(reference count)。智能指針類將一個計數器與類指向的對象相關聯,引用計數跟蹤該類有多少個對象共享同一指針。每次創建類的新對象時,初始化指針並將引用計數置爲1;當對象作爲另一對象的副本而創建時,拷貝構造函數拷貝指針並增加與之相應的引用計數;對一個對象進行賦值時,賦值操作符減少左操作數所指對象的引用計數(如果引用計數爲減至0,則刪除對象),並增加右操作數所指對象的引用計數;調用析構函數時,構造函數減少引用計數(如果引用計數減至0,則刪除基礎對象)。 智能指針就是模擬指針動作的類。所有的智能指針都會重載 -> 和 * 操作符。智能指針還有許多其他功能,比較有用的是自動銷燬。這主要是利用棧對象的有限作用域以及臨時對象(有限作用域實現)析構函數釋放內存。當然,智能指針還不止這些,還包括複製時可以修改源對象等。智能指針根據需求不同,設計也不同(寫時複製,賦值即釋放對象擁有權限、引用計數等,控制權轉移等)。
五、實驗步驟
1.建立一個名爲smartpoint.cpp文件
2.定義僅由smartcount類使用的smartpoint類,用於封裝使用計數和相關指針
- class smartpoint
- {
- int *ip;
- int P_use;
- smartpoint(int *p) : ip(p) , P_use(1)//初始化指針並將引用計數置爲1
- {
- cout << "smartpoint constructor spoke !" << endl;
- }
- ~smartpoint()//定義析構函數
- {
- delete ip;
- cout << "smartpoint distructor spoke !" << endl;
- }
- friend class smartcount;// 將smartcount類設置爲友元,使其成員可以訪問smartpoint的成員
- };
定義smartcount類用於訪問smartpoint類
- class smartcount
- {
- public:
- smartcount(int *p, int i) :st_conut (new smartpoint(p)) , val(i)// 構造函數:p是指向已經動態創建的int對象指針
- {
- cout << "smartcount constructor spoke ! " << "p_use = " <<st_conut->P_use << endl;
- }
- smartcount(const smartcount& orig) : st_conut(orig.st_conut) , val(orig.val)// 複製構造函數:複製成員並將使用計數加1
- {
- ++st_conut->P_use;
- cout << "smartcount copy constructor spoke ! " << "P_use = " << st_conut->P_use << endl;
- }
- smartcount& operator=(const smartcount&);// 賦值操作符
- ~smartcount()// 析構函數:如果計數爲0,則刪除smartpoint對象
- {
- cout << "smartcount distructor spoke ! " << "p_use = " << st_conut->P_use << endl;
- if (--st_conut->P_use == 0)
- delete st_conut;
- }
- private:
- smartpoint *st_conut; //指向使用計數類smartpoint
- int val;
- };
注:代碼有參考網絡資源
保存進行運行
六、實驗小結及問題分析
(1)不管指針成員。複製時只複製指針,不復制指針指向的對象。當其中一個指針把其指向的對象的空間釋放後,其它指針都成了懸浮指針。這是一種極端
(2)當複製的時候,即複製指針,也複製指針指向的對象。這樣可能造成空間的浪費。因爲指針指向的對象的複製不一定是必要的。
(3) 第三種就是一種折中的方式。利用一個輔助類來管理指針的複製。原來的類中有一個指針指向輔助類,輔助類的數據成員是一個計數器和一個指針(指向原來的)(此爲本次智能指針實現方式)。
總之智能指針(smart pointer)是存儲指向動態分配(堆)對象指針的類,用於生存期控制,能夠確保自動正確的銷燬動態分配的對象,防止內存泄露。