zoukankan      html  css  js  c++  java
  • 自己动手实现智能指针auto_ptr

    面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍。

    auto_ptr归根到底是一个模版类,那么这个类要实现哪些功能呢?如下:

    /*
    一个智能指针应该有以下操作:
    1.Auto_ptr<T> ap;            //创建名为ap的为绑定Auto_ptr对象
    2.Auto_ptr<T> ap(p);         //创建 ap 的Auto_ptr对象,ap用友指针 p 指向的对象。该构造函数为explicit
    3.Auto_ptr<T> ap1(ap2)              //创建名为ap1的Auto_ptr对象,ap1保存原来存在ap2中的指针。将所有权转给ap1,ap2成为未绑定的Auto_ptr对象
    4.ap1 = ap2            //将所有权从ap2转给ap1。删除ap1指向的对象并且使ap1指向ap2指向的对象,使ap2成为未绑定的
    5.~ap                //析构函数。删除ap指向的对象
    6.*ap                                            //返回对ap所绑定对象的引用
    7.ap->                                          //返回ap保存的指针
    8.ap.reset(p)                                //如果ap与p的值不同,则删除ap指向的独享并且将ap绑定到p
    9.ap.release()                               //返回ap所保存的指针并且是ap成为未绑定的
    10.ap.get()                                   //返回ap保存的指针
    */

    具体代码如下:

     1 template<class T>
     2 class Auto_ptr {
     3 private:
     4     T *ptr;        //真正的指针值
     5     mutable bool owns;    //是否拥有该指针
     6 public:
     7     //不可以隐式转化的构造函数
     8     explicit Auto_ptr(T *p = 0):ptr(p),owns((bool)p){}    //不能隐式转化,例如Auto_ptr<int> Ap = new int(1024) //error
     9     //复制构造函数
    10     //Auto_ptr(const Auto_ptr& a):ptr(a.ptr),owns(a.owns){ a.owns = 0;}
    11     //泛化版的复制构造函数
    12     template <class U>
    13     Auto_ptr(const Auto_ptr<U>& a):ptr(a.ptr),owns(a.owns){ a.owns = 0;}
    14 
    15     //重载赋值操作符
    16     Auto_ptr& operator=(const Auto_ptr& a)
    17     {
    18         if(&a != this)    //防止自身赋值
    19         {
    20             if(owns)
    21                 delete ptr;
    22             owns = a.owns;
    23             ptr  = a.ptr;
    24             a.owns = 0;
    25         }
    26     }
    27     //泛化版的重载赋值操作符
    28     template<class U>
    29     Auto_ptr& operator=(Auto_ptr<U>& a)
    30     {
    31         if (&a != this)
    32         {
    33             if(owns)
    34                 delete ptr;
    35             owns = a.owns;
    36             ptr  = a.ptr;
    37             a.owns = false;
    38         }
    39         return *this;
    40     }
    41     T& operator  *() const {return *ptr;} 
    42     T* operator ->() const {return ptr;}
    43     T* get() const { return ptr;}
    44     void reset(T *p = 0)
    45     {
    46         if(owns)
    47         {
    48             if(ptr != p)    //如果p 和 ptr的值不同    
    49             {
    50                 delete ptr;    //删除原来指向的对象
    51             }                //else付过相同肯定不能删除啊
    52         }
    53         ptr = p;            //这里赋值时安全的,机试ptr和p原来相等
    54     }
    55     T* release() const{ owns = false;return ptr;}
    56     ~Auto_ptr(){if(owns) {cout << "析构!"<< endl;delete ptr;}}
    57 };

    测试代码如下:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     Auto_ptr<int> Ap;
     8     Auto_ptr<int> Ap1(new int(1024));
     9     //Auto_ptr<int> Ap2 = new int(1024);    //error
    10     //if(Ap == NULL)        //error
    11     if(Ap.get() == NULL)
    12     { 
    13         cout << "Ap is NULL!" << endl;
    14     }
    15     cout << "Before = Ap1 value is:" << Ap1.get() << endl;
    16     Auto_ptr<int> Ap3 ;
    17     Ap3 = Ap1;
    18     cout << "After  = Ap1 value is:" << Ap1.get() << endl;
    19     int *p = Ap3.release();
    20     cout << "Ap3 value is:" << Ap3.get() << endl; 
    21     Ap3.reset(new int(12));
    22     cout << "Ap3 value is:" << Ap3.get() << endl;
    23     return 0;
    24 }

    测试的结果:

    由上图我们可以看到Ap1在 赋值=之前和之后都指向的地址都是00620FB8,说明赋值并没有改变智能指针的指向,只是将拥有的标志owns改变了。通过reset函数可以重新绑定智能指针!

  • 相关阅读:
    Commons JXPath
    10到十分精彩的智力题,你能过关几道?
    程序员下班电脑不关机的5大原因,你中招了吗?
    程序员下班电脑不关机的5大原因,你中招了吗?
    MySQL的一些概念笔记
    MySQL的一些概念笔记
    Shell中I/O重定向的用法笔记
    Shell中I/O重定向的用法笔记
    Shell重定向的概念笔记
    Shell重定向的概念笔记
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/3679260.html
Copyright © 2011-2022 走看看