关于智能指针auto_ptr

智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个

感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解。

本篇主要介绍auto_ptr

其特点如下:

1.首先auto_ptr智能指针是个封装好的类;

2.是采用栈上的指针去管理堆上的内容,所以auto_ptr所管理的对象必须是new出来的,也不能是malloc出来的,

  原因:在auto_ptr的实现机制中,采用的是delete 掉一个指针,该delete一方面是调用了指针所指对象的析构函数(这也是为什么采用智能指针,new了一个对象,但是不用delete的原因),另一方面释放了堆空间的内存;

3.一块堆上的内存不能被两个智能指针同时指向这个就是所有权和管理权的问题),想想也是,如果两个智能指针同时指向的话,每个智能指针对象析构的时候,都会调用一次delete,导致堆空间内存被释放两次,然而这是不被允许的。

4.aut0_ptr不能管理数组,因为析构调用的是delete,如果管理数组的话,需要调用delete[];

相比于普通指针的额优点就是:

普通指针在new 和delete之间发生异常,并且异常不能被捕获的话,就不会执行delete,那么这片内存就不能被回收。

但是auto_ptr就不会存在这样的问题。

其具体实现代码如下:应该是别人写的啊,感觉写的很不错啊,基本实现了auto_ptr的所有功能,而且容易读懂!

 1 //auto_ptr.h
 2 
 3 #ifndef AUTO_PTR_H
 4 #define AUTO_PTR_H
 5 
 6 template<typename T>
 7 class auto_ptr
 8 {
 9 public :
10     //使用explicit关键字避免隐式转换
11     explicit auto_ptr(T* p=0);
12 
13     ~auto_ptr();
14 
15     //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr
16     template<typename U>
17     auto_ptr(auto_ptr<U>& rhs);
18 
19     template<typename U>
20     auto_ptr<T>& operator=(auto_ptr<U>& rhs);
21 
22     T& operator*() const;
23     T* operator->() const;
24 
25     //返回原始对象的指针
26     T* get() const;
27     //放弃指针的所有权
28     T* release();
29     //删除原有指针并获得指针的p的所有权
30     void reset(T* p=0);
31 
32 private:
33     T* pointee;
34 
35 };
36 
37 template<typename T>
38 auto_ptr<T>::auto_ptr(T* p)
39     :pointee(p)
40 {}
41 
42 template<typename T>
43 template<typename U>
44 auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
45     :pointee(rhs.release())
46 {}
47 
48 template<typename T>
49 auto_ptr<T>::~auto_ptr()
50 {
51     delete pointee;
52 }
53 
54 template<typename T>
55 template<typename U>
56 auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
57 {
58     if(this!=&rhs)
59         reset(rhs.release());
60     return *this;
61 }
62 
63 template<typename T>
64 T& auto_ptr<T>::operator*() const
65 {
66     return *pointee;
67 }
68 
69 template<typename T>
70 T* auto_ptr<T>::operator->() const
71 {
72     return pointee;
73 }
74 
75 template<typename T>
76 T* auto_ptr<T>::get() const
77 {
78     return pointee;
79 }
80 
81 template<typename T>
82 T* auto_ptr<T>::release()
83 {
84     T* oldpointee=pointee;
85     pointee=0;
86     return oldpointee;
87 }
88 
89 template<typename T>
90 void auto_ptr<T>::reset(T* p)
91 {
92     if(pointee!=p)
93     {
94         delete pointee;
95         pointee=p;
96     }
97 }
98 
99 #endif
 1 //Item.h
 2 #ifndef ITEM_H
 3 #define ITEM_H
 4 
 5 class Item
 6 {
 7 public:
 8     Item(void);
 9     ~Item(void);
10 
11     void PrintContent() const;
12 };
13 
14 #endif
15 
16 //Item.cpp
17 using std::cout;
18 using std::endl;
19 
20 Item::Item(void)
21 {
22     cout<<"constructor"<<endl;
23 }
24 
25 Item::~Item(void)
26 {
27     cout<<"Destorying....."<<endl;
28 }
29 
30 void Item::PrintContent() const
31 {
32     cout<<"Here is the content"<<endl;
33 }
#include <iostream>
#include "auto_ptr.h"
#include "Item.h"

using std::cout;

int main()
{
    
    auto_ptr<Item> itemPtr(new Item);
    itemPtr->PrintContent();
    auto_ptr<Item> itemPtr2(itemPtr);
    itemPtr2->PrintContent();
    return 0;
}
原文地址:https://www.cnblogs.com/limera/p/auto_ptr.html