1. 程式人生 > >智能指針之 auto_ptr

智能指針之 auto_ptr

實現 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>
  6
class 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; 18
cout << "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