智能指針

一、實驗目的

●熟悉智能指針

●對智能指針進行設計和實現

二、實驗實驗環境: 在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類,用於封裝使用計數和相關指針

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. class smartpoint  
  2. {  
  3.     int *ip;  
  4.     int P_use;  
  5.     smartpoint(int *p) : ip(p) , P_use(1)//初始化指針並將引用計數置爲1  
  6.     {  
  7.        cout << "smartpoint constructor spoke !" << endl;  
  8.     }  
  9.     ~smartpoint()//定義析構函數  
  10.     {  
  11.        delete ip;  
  12.        cout << "smartpoint distructor spoke !" << endl;  
  13.     }  
  14.     friend class smartcount;// 將smartcount類設置爲友元,使其成員可以訪問smartpoint的成員  
  15. };  

定義smartcount類用於訪問smartpoint類

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. class smartcount  
  2. {  
  3. public:  
  4.    smartcount(int *p, int i) :st_conut (new smartpoint(p)) , val(i)// 構造函數:p是指向已經動態創建的int對象指針  
  5.     {  
  6.         cout << "smartcount constructor spoke ! " << "p_use = " <<st_conut->P_use << endl;  
  7.     }  
  8.   
  9.     smartcount(const smartcount& orig) : st_conut(orig.st_conut) , val(orig.val)// 複製構造函數:複製成員並將使用計數加1  
  10.     {  
  11.        ++st_conut->P_use;  
  12.        cout << "smartcount copy constructor spoke ! " << "P_use = " << st_conut->P_use << endl;  
  13.     }  
  14.   
  15.     smartcount& operator=(const smartcount&);// 賦值操作符  
  16.     ~smartcount()// 析構函數:如果計數爲0,則刪除smartpoint對象  
  17.     {  
  18.       cout << "smartcount distructor spoke ! " << "p_use = " << st_conut->P_use << endl;  
  19.         if (--st_conut->P_use == 0)  
  20.           delete st_conut;  
  21.     }  
  22.   
  23.       
  24. private:  
  25.     smartpoint *st_conut;   //指向使用計數類smartpoint  
  26.     int val;  
  27. };  

注:代碼有參考網絡資源

保存進行運行

六、實驗小結及問題分析

    (1)不管指針成員。複製時只複製指針,不復制指針指向的對象。當其中一個指針把其指向的對象的空間釋放後,其它指針都成了懸浮指針。這是一種極端

    (2)當複製的時候,即複製指針,也複製指針指向的對象。這樣可能造成空間的浪費。因爲指針指向的對象的複製不一定是必要的。

   (3) 第三種就是一種折中的方式。利用一個輔助類來管理指針的複製。原來的類中有一個指針指向輔助類,輔助類的數據成員是一個計數器和一個指針(指向原來的)(此爲本次智能指針實現方式)。

    總之智能指針(smart pointer)是存儲指向動態分配(堆)對象指針的類,用於生存期控制,能夠確保自動正確的銷燬動態分配的對象,防止內存泄露。


發佈了39 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章