• 再论智能指针(下)


    1. SharedPointer的设计要点

    (1)使用类模板技术

    (2)通过计数机制(ref)标记堆内存:

    • 堆内存被执向时,ref++
    • 堆内存被释放时,ref--
    • ref为零时释放所执向的堆内存

    2. 计数机制原理剖析

    3. SharedPointer类的声明

     1 template <typename T>
     2 class SharedPointer : public Pointer<T>
     3 {
     4 protected:
     5     int* m_refCount; //计数机制成员
     6 public:
     7     SharedPointer(T* p = NULL);
     8     SharedPointer(const SharedPointer<T>& obj);
     9     
    10     SharedPointer<T>& operator=(const SharedPointer<T>& obj);
    11     
    12     void clear(); //将当前指针置为空
    13     
    14     //由于SharedPointer支持多个对象同时指向一片堆空间
    15     //因此必须支持比较操作!
    16     bool operator==(const SharedPointer<T>& obj);
    17     bool operator!=(const SharedPointer<T>& obj);
    18     
    19     ~SharedPointer();
    20 };

    note:

    代码中的计数变量是使用了一个指针指向的堆空间,这样做是由于:

    智能指针指向的对象是在堆空间,为了保持计数变量智能指针指向的对象保持相同的生命周期,计数变量应该也是在堆空间中。

    4. SharedPointer类的实现

    SharedPointer.h

      1 #ifndef _SHAREDPOINTER_H_
      2 #define _SHAREDPOINTER_H_
      3 
      4 #include "Pointer.h"
      5 #include "exception.h"
      6 #include <cstdlib>
      7 
      8 namespace DataStructureLib 
      9 {
     10     template <typename T>
     11 
     12     class SharedPointer :public Pointer<T>
     13     {
     14     protected:
     15         int* m_ref;//计数机制成员
     16         
     17         void assign(const SharedPointer<T>& obj)
     18         {
     19             this->m_pointer=obj.m_pointer;
     20             this->m_ref=obj.m_ref;
     21 
     22             if ( obj.m_ref)
     23             {    
     24                 (*this->m_ref)++;
     25             }     
     26         } 
     27     public:
     28         SharedPointer(T* p=NULL):Pointer(NULL) //构造函数  显式调用父类的构造函数
     29         {
     30             if (p)
     31             {
     32                 this->m_ref=static_cast<int*>(malloc(sizeof(int)));
     33                 if (this->m_ref)
     34                 {
     35                     *(this->m_ref)=1;
     36                     this->m_pointer=p;
     37                     
     38                 }
     39                 else
     40                     THROW_EXCEPTION(NotEnoughMemoryException,"No memory to create SharedPointer object ... ");
     41             }
     42         }
     43 
     44         SharedPointer(const SharedPointer<T>& obj):Pointer(NULL)
     45         {
     46             assign(obj);
     47         }
     48 
     49       SharedPointer<T>& operator =(const SharedPointer<T>& obj)
     50       {
     51           if (this!=&obj)
     52           {
     53              clear();//如果当前的sharepointer指针已经指向 另外一片堆空间,应该先置空当前指针,不让它指向任何堆空间
     54              assign(obj);
     55           }
     56          
     57 
     58           return *this;
     59       }
     60 
     61       void clear()
     62       {//置空函数
     63           T* todel=this->m_pointer;
     64           int *ref=this->m_ref;
     65 
     66           this->m_pointer=NULL;
     67           this->m_ref=NULL;
     68 
     69           if ( ref)
     70           {
     71               (*ref)--;//释放一个指针减1
     72 
     73               if (*ref==0)//若堆空间没有对应的指针指向
     74               {
     75                   free(ref);
     76                   ref=NULL;
     77                  
     78                   delete todel;
     79               }
     80           }
     81       }
     82 
     83       ~SharedPointer()
     84       {
     85           clear();
     86       }
     87     };
     88     
     89     
     90     
     91     //由于SharedPointer支持多个对象同时指向一片堆空间。因此必须支持比较操作!
     92 
     93     template<typename T>
     94     bool operator == (const SharedPointer<T>& l,const SharedPointer<T>& obj)
     95     {
     96         return (l.get()==obj.get());
     97     }
     98 
     99     template<typename T>
    100     bool operator !=(const SharedPointer<T>& l,const SharedPointer<T>& obj)
    101     {
    102         return !(l==obj);
    103     }
    104 
    105 
    106 
    107 }
    108 
    109 #endif

    测试代码:

     1 #include<iostream>
     2 #include "SharedPointer.h"
     3 using namespace std;
     4 using namespace DataStructureLib;
     5 
     6 class Test : public Object
     7 {
     8     
     9 public:
    10     int m_value;
    11     Test():m_value(0)
    12     {
    13         cout << "Test()" << endl;
    14     }
    15 
    16     ~Test()
    17     {
    18         cout <<"~Test()" << endl;
    19     }
    20 };
    21 int main(int argc, char const *argv[])
    22 {
    23     SharedPointer<Test> sp0 = new Test();
    24     SharedPointer<Test> sp1 = sp0;
    25     SharedPointer<Test> sp2 = NULL;
    26 
    27       sp2 = sp1;
    28 
    29       sp0->m_value=100;
    30 
    31       cout << sp0->m_value << endl;
    32       cout << sp1->m_value << endl;
    33       cout << sp2->m_value << endl;
    34     //system("pause"); 
    35     return 0;
    36 }

    结果

    5.智能指针使用军规

    (1)只能用来指向堆空间中的单个对象(变量)

    (2)不同类型的智能指针对象不能混合使用

    (3)不要使用delete释放智能指针指向的堆空间

    6.小结

     (1)SharedPointer最大程度的模拟了原生指针的行为

     (2)计数机制确保多个智能指针合法的指向同一片堆空间

     (3)智能指针只能用于指向堆空间中的内存(不能是栈空间或者全局区的内存数据)

     (4)不同类型的智能指针(上一节和这一节的两种)不要混合使用

     (5)堆对象的生命周期由智能指针进行管理(申请和删除)

  • 相关阅读:
    每日总结6.14
    每日总结6.13
    每日总结6.12
    每日总结6.11
    用户故事与敏捷方法阅读笔记4
    用户故事与敏捷方法阅读笔记3
    团队冲刺第一阶段燃尽图
    团队冲刺10
    智能物联网:将人工智能的力量带入物联网
    MyEclipse修改文件后Building workspace时间过长
  • 原文地址:https://www.cnblogs.com/zhaobinyouth/p/9769943.html
Copyright © 2020-2023  润新知