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已经不再拥有任何对象了。