zoukankan      html  css  js  c++  java
  • 第二十八课 再论智能指针(下)

    多个智能指针指向同一片堆空间的需求是巨大的。

    计数变量也是在堆空间里面定义的,它的生命周期和对象的生命周期相同。

    添加SharedPointer.h文件:

     1 #ifndef SHAREDPOINTER_H
     2 #define SHAREDPOINTER_H
     3 
     4 #include <cstdlib>
     5 #include "Pointer.h"
     6 #include "Exception.h"
     7 
     8 namespace DTLib
     9 {
    10 
    11 template < typename T >
    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_ref = obj.m_ref;
    20         this->m_pointer = obj.m_pointer;
    21 
    22         if( this->m_ref )
    23         {
    24             (*this->m_ref)++;
    25         }
    26     }
    27 
    28 public:
    29     SharedPointer(T& p = NULL) : m_ref(NULL)
    30     {
    31         if( p )
    32         {
    33             this->m_ref = static_cast<int*>(std::malloc(sizeof(int)));
    34 
    35             if( this->m_ref )
    36             {
    37                 *(this->m_ref) = 1;
    38                 this->m_pointer = p;
    39             }
    40             else
    41             {
    42                 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create SharesPointer object ...");
    43             }
    44         }
    45     }
    46 
    47     SharedPointer(const SharedPointer<T>& obj)
    48     {
    49         assign(obj);
    50     }
    51 
    52     SharedPointer<T>& operator= (const SharedPointer<T>& obj)
    53     {
    54         if( this != &obj )
    55         {
    56             clear();  //先将当前智能指针置空
    57 
    58             assign(obj);
    59         }
    60 
    61         return *this;
    62     }
    63 
    64     void clear()
    65     {
    66         T* toDel = this->m_pointer;
    67         int* ref = this->m_ref;
    68 
    69         this->m_pointer = NULL;
    70         this->m_ref = NULL;
    71 
    72         if( ret )
    73         {
    74             (*ref)--;    //当前指针指向的堆空间计数减1
    75 
    76             if( *ref == 0 )
    77             {
    78                 free(ref);
    79 
    80                 delete toDel;
    81             }
    82         }
    83     }
    84 
    85     ~SharedPointer()
    86     {
    87         clear();
    88     }
    89 };
    90 
    91 }
    92 
    93 #endif // SHAREDPOINTER_H

    测试程序如下:

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

    运行结果如下:

     第二个测试程序:

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

    结果如下:

     一个堆空间被三个指针指向,最终只释放一次。

    编译警告:

    提示我们要在SharedPointer的拷贝构造函数中显式的调用父类的拷贝构造函数。

    最终的SharedPointer.h内容如下:

      1 #ifndef SHAREDPOINTER_H
      2 #define SHAREDPOINTER_H
      3 
      4 #include <cstdlib>
      5 #include "Pointer.h"
      6 #include "Exception.h"
      7 
      8 namespace DTLib
      9 {
     10 
     11 template < typename T >
     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_ref = obj.m_ref;
     20         this->m_pointer = obj.m_pointer;
     21 
     22         if( this->m_ref )
     23         {
     24             (*this->m_ref)++;
     25         }
     26     }
     27 
     28 public:
     29     SharedPointer(T* p = NULL) : m_ref(NULL)
     30     {
     31         if( p )
     32         {
     33             this->m_ref = static_cast<int*>(std::malloc(sizeof(int)));
     34 
     35             if( this->m_ref )
     36             {
     37                 *(this->m_ref) = 1;
     38                 this->m_pointer = p;
     39             }
     40             else
     41             {
     42                 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create SharesPointer object ...");
     43             }
     44         }
     45     }
     46 
     47     SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL)
     48     {
     49         assign(obj);
     50     }
     51 
     52     SharedPointer<T>& operator= (const SharedPointer<T>& obj)
     53     {
     54         if( this != &obj )
     55         {
     56             clear();  //先将当前智能指针置空
     57 
     58             assign(obj);
     59         }
     60 
     61         return *this;
     62     }
     63 
     64     void clear()
     65     {
     66         T* toDel = this->m_pointer;
     67         int* ref = this->m_ref;
     68 
     69         this->m_pointer = NULL;
     70         this->m_ref = NULL;
     71 
     72         if( ref )
     73         {
     74             (*ref)--;    //当前指针指向的堆空间计数减1
     75 
     76             if( *ref == 0 )
     77             {
     78                 free(ref);
     79 
     80                 delete toDel;
     81             }
     82         }
     83     }
     84 
     85     ~SharedPointer()
     86     {
     87         clear();
     88     }
     89 };
     90 
     91 template < typename T >
     92 bool operator ==(const SharedPointer<T>& l, const SharedPointer<T>& r)
     93 {
     94     return (l.get() == r.get());
     95 }
     96 
     97 template < typename T >
     98 bool operator !=(const SharedPointer<T>& l, const SharedPointer<T>& r)
     99 {
    100     return !(l == r);
    101 }
    102 
    103 }
    104 
    105 #endif // SHAREDPOINTER_H

     ==和!=重载为全局的。

    智能指针使用军规:

     小结:

  • 相关阅读:
    UVA 10056 What is the Probability ?
    Reporting Services Report 带参数
    頁面刷新後,滾動條位置保持不變
    use this as the default and do not ask again
    JQuery Tab 滑动们导航菜单效果
    poj3256
    poj2060
    poj3280
    poj3261
    poj2135
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9653005.html
Copyright © 2011-2022 走看看