2014年8月8日 星期五

[ C++ Gossip ] Object Basic : 封裝 - auto_ptr 自動管理配置資源

來源自 這裡 
Preface: 
對於使用 new 動態配置的資源,在不使用時必須記得 delete,以釋放記憶體空間,然而動態記憶體配置很容易發生忘了 delete,或是對同一個記憶體 位址 delete 兩次(例如一個物件被指定給兩個指標),或是對一個已經被 delete 的位址再作讀寫動作. 

auto_ptr 自動管理配置資源: 
C++ 標準函式庫中提供 auto_ptr,可以協助您動態管理 new 而建立的物件,要使用 auto_ptr,您要含入 memory 表頭檔,例如: 
auto_ptr 可以指向一個以 new 建立的物件, auto_ptr 的生命週期結束後,所指向的物件之資源也會被釋放,在建立 auto_ptr 時必須指 定目標物件之型態,例如: 
  1. auto_ptr<int> iPtr (new int(100));  
  2. auto_ptr sPtr (new string("caterpillar"));  
操作 auto_ptr 就像操作沒有使用 auto_ptr 的指標一樣,例如: 
  1. cout << *iPtr << endl; // 顯示100  
  2. if(sPtr->empty())  
  3.     cout << "字串為空" << endl;  
您也可以建立一個未指向任何物件的 auto_ptr 就像操作沒有使用 auto_ptr,例如: 
  1. auto_ptr<int> iPtr;  
未指向任何物件的 auto_ptr 就像操作沒有使用 auto_ptr 不可以取值,否則會發生不可預期之結果,既然不可取值,如何判斷它是否有指向物件呢?您可以使用 get() 函式,它會傳 回所指向物件的位址,如果傳回 0,表示不指向任何物件,如果不指向任何物件,您可以使用 reset() 來讓它指向一個物件,例如: 
  1. if(iPtr.get() == 0) {  
  2.     iPtr.reset(new int(100));  
  3. }  
reset() 可以接受一個指標或是 0 表示不指向任何物件,reset() 會先 delete 目前指向的物件,然後重新指向新的物件,您也可以使用 release() 釋 auto_ptr 管理所指向物件的職責. 

auto_ptr 可以使用另一個 auto_ptr 來建立,這會造成所有權的轉移,例如: 
  1. #include   
  2. #include   
  3. #include "SafeArray.h"  
  4. using namespace std;  
  5.   
  6.   
  7. int main()  
  8. {  
  9.   auto_ptr ptr1(new SafeArray(1));  
  10.   ptr1->set(0,1);  
  11.   cout << "ptr1 address: " << ptr1.get() << "(" << ptr1->get(0) << ")" << endl;  
  12.   auto_ptr ptr2(new SafeArray(1));  
  13.   ptr2->set(0,2);  
  14.   cout << "ptr2 address: " << ptr2.get() << "(" << ptr2->get(0) << ")" << endl;  
  15.   cout << "Assign ptr2 to ptr1..." << endl;  
  16.   ptr2 = ptr1;  
  17.   cout << "ptr2 address: " << ptr2.get() << "(" << ptr2->get(0) << ")" << endl;  
  18.   cout << "ptr1 address: " << ptr1.get() << endl;  
  19.   return 0;  
  20. }  
ptr2 所指向的物件會先被 delete,然後 ptr1 的屬性會複製至 ptr2,也就是 ptr1 所指向的物件,現在由 ptr2 指向它了,ptr1 不再負責 所指向物件的資源釋放. 執行結果如下: 
$ ./testAutoPtr
ptr1 address: 0x1668010(1)
ptr2 address: 0x1668050(2)
Assign ptr2 to ptr1...
Deconstruction... # ptr2 所指向物件呼叫 deconstruction 已重新指向 ptr1 的物件
ptr2 address: 0x1668010(1) # 此時 ptr2 指向 ptr1 的物件!
ptr1 address: 0 # 此時 ptr1 指向 0
Deconstruction... # ptr2 所指向物件呼叫 deconstruction

auto_ptr 的資源維護動作是以 inline 的方式來完成,也就是在編譯時會被擴展開來,所以使用auto_ptr 並不會犧牲效率. 最後要注意的是,auto_ptr 不能用來管理動態配置而來的陣列,如果用它來管理動態配置而來的陣列,結果是不可預期的

Supplement: 
Cplusplus > Reference > memory > auto_ptr 
Automatic Pointer [deprecated]
This class template provides a limited garbage collection facility for pointers, by allowing pointers to have the elements they point to automatically destroyed when the auto_ptr object is itself destroyed...

[C++ 小學堂] 關鍵字 inline 介紹

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...