智能指針之 auto_ptr
阿新 • • 發佈:2018-04-23
實現 16px ID ddr c++ 調用 pri stream GC
C++的auto_ptr所做的事情,就是動態分配對象以及當對象不再需要時自動執行清理,該智能指針在C++11中已經被棄用,轉而由unique_ptr替代,
那這次使用和實現,就具體講一下auto_ptr被棄用的原因,(編譯平臺:Linux centos 7.0 編譯器:gcc 4.8.5 )
首先使用std::auto_ptr時,需要#include <memory>頭文件,具體使用代碼如下(文件名:test_ptr.cpp):
#include <memory> #include <iostream> using namespace std; class Test { public: Test() { cout << "construct.." << endl; } ~Test() { cout << "destruct.." << endl; } }; void test() { } int main() { Test* p = new Test(); auto_ptr<Test> ap(p); return 0; }
執行上述代碼,我們可以看到,程序結束時,在堆上申請的對象,自動執行了析構函數,將內存釋放了
[root@localhost code]# g++ -g -o autop test_ptr.cpp [root@localhost code]# ./autop construct.. destruct.. [root@localhost code]#
具體實現代碼如下,構造函數只實現了初始化構造和拷貝構造:
1 #include <iostream> 2 3 using namespace std; 4 5 template<typename T> 6class auto_pt 7 { 8 public: 9 explicit auto_pt(T* p = NULL):m_ptr(p) 10 { 11 p = NULL; 12 cout << "auto_ptr construct" << endl; 13 } 14 15 auto_pt(auto_pt& autoPtr):m_ptr(autoPtr.m_ptr) 16 { 17 autoPtr.m_ptr = NULL; 18cout << "copy auto_ptr construct" << endl; 19 } 20 21 auto_pt& operator = (auto_pt& p) 22 { 23 if(this != &p) 24 { 25 if(m_ptr != NULL) 26 { 27 delete m_ptr; 28 m_ptr = p.m_ptr; 29 p.m_ptr = NULL; 30 } 31 } 32 33 return *this; 34 } 35 36 ~auto_pt() 37 { 38 if(m_ptr != NULL) 39 { 40 cout << "auto_ptr destruct" << endl; 41 delete m_ptr; 42 m_ptr = NULL; 43 } 44 45 } 46 47 T* Get() 48 { 49 return m_ptr; 50 } 51 52 T& operator*() 53 { 54 return *m_ptr; 55 } 56 57 T* operator->() 58 { 59 return m_ptr; 60 } 61 62 private: 63 T* m_ptr; 64 }; 65 66 class Test 67 { 68 public: 69 Test() 70 { 71 cout << "construct.." << endl; 72 } 73 74 ~Test() 75 { 76 cout << "destruct.." << endl; 77 } 78 79 void method() 80 { 81 cout << "welcome Test.." << endl; 82 } 83 }; 84 85 void f(auto_pt<Test>ap) 86 { 87 cout << "funtion f :"; 88 ap->method(); 89 } 90 91 int main() 92 { 93 //baseic test 94 Test* p = new Test(); 95 cout << "address0 [%p]" << p << endl; 96 auto_pt<Test> ap(p); 97 98 cout << "address1 [%p]" << ap.Get()<< endl; 99 cout << "address2 [%p]" << &ap << endl; 100 cout << "address3 [%p]" << &(*ap) << endl; 101 102 ap.Get()->method(); 103 (*ap).method(); 104 ap->method(); 105 106 return 0; 107 }
打印結果:
1 [root@localhost code]# g++ -o autop_test test.cpp 2 [root@localhost code]# ./autop_test 3 construct.. 4 address0 [%p]0xb77010 5 auto_ptr construct 6 address1 [%p]0xb77010 7 address2 [%p]0x7ffe8b25f510 8 address3 [%p]0xb77010 9 welcome Test.. 10 welcome Test.. 11 welcome Test.. 12 auto_ptr destruct 13 destruct.. 14 [root@localhost code]#
大概實現就是這樣,基本和標準庫差不多,除了另外兩種類型的構造函數沒有加進去
那在我們使用及實現的過程中,發現這個auto_ptr在使用過程中會有如下風險,因此在C++11中已經不再使用,那在我們開發過程中,也最好不要再使用
1. 兩個auto_ptr指向同一塊內存,造成多次釋放
1 //if 2 object point one address, application will die 2 Test* p1 = new Test(); 3 4 auto_pt<Test> ap1(p1); 5 auto_pt<Test> ap2(p1);
2. 復制完成後,會將復制的對象置空,因此不能繼續使用
1 int*p=new int(); 2 auto_pt<int>ap1(p); 3 auto_pt<int>ap2=ap1; 4 (*ap1).method();//錯誤,此時ap1只剩一個null指針在手了
3. 函數形參使用值傳遞,會發生拷貝操作,導致ap1對象權限獲取不到了
1 void f(auto_pt<int>ap) 2 { 3 (*ap).method(); 4 } 5 6 auto_pt<int>ap1(new int(0)); 7 f(ap1); 8 (*ap1).method();;//錯誤,經過f(ap1)函數調用,ap1已經不再擁有任何對象了。
智能指針之 auto_ptr