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函数可以重新绑定智能指针!

  • 相关阅读:
    FEniCS 1.1.0 发布,计算算术模型
    Piwik 1.10 发布,增加社交网站统计
    淘宝褚霸谈做技术的心态
    CyanogenMod 10.1 M1 发布
    Druid 发布 0.2.11 版本,数据库连接池
    GNU Gatekeeper 3.2 发布
    Phalcon 0.9.0 BETA版本发布,新增大量功能
    EUGene 2.6.1 发布,UML 模型操作工具
    CVSps 3.10 发布,CVS 资料库更改收集
    Opera 移动版将采用 WebKit 引擎
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/3679260.html
Copyright © 2011-2022 走看看