第28课 - 再论智能指针(下)

1、再论智能指针

        课程目标

            - 完成SharedPointer类的实现



            SharedPointer类的设计要点

                -类模板 

                        通过计数机制( ref )标识堆内存 

                                堆内存被指向时: ref++ 

                                指针被置空时: ref--

                                ref == 0时:释放堆内存 

 -

        计数机制原理剖析 



        SharedPointer类的声明



        智能指针的比较 

                由于SharedPointer支持多个对象同时指向 

                一片堆空间;因此,必须支持比较操作!


2、编程实验 

智能指针的新成员     SharedPointer.h

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


因此必须修改Pointer.h

  1. #ifndef POINTER_H  
  2. #define POINTER_H  
  3.   
  4. #include"Object.h"  
  5.   
  6. namespace DTLib  
  7. {  
  8.   
  9. template <typename T>  
  10. class Pointer : public Object  
  11. {  
  12. protected:  
  13.     T* m_pointer;  
  14. public:  
  15.     Pointer(T* p = NULL)  
  16.     {  
  17.         m_pointer = p;  
  18.     }  
  19.     T* operator -> ()  
  20.     {  
  21.         return m_pointer;  
  22.     }  
  23.     T& operator * ()  
  24.     {  
  25.         return *m_pointer;  
  26.     }  
  27.     const T* operator -> () const  
  28.     {  
  29.         return m_pointer;  
  30.     }  
  31.     const T& operator * () const  
  32.     {  
  33.         return *m_pointer;  
  34.     }  
  35.     bool isNull() const  
  36.     {  
  37.         return m_pointer == NULL;  
  38.     }  
  39.     T* get() const  
  40.     {  
  41.         return m_pointer;  
  42.     }  
  43.     //只要不实现析构函数,就是抽象类(继承了顶层父类)  
  44. };  
  45.   
  46. }  
  47.   
  48. #endif // POINTER_H  

main.cpp

#include <iostream>
#include"SharedPointer.h"
 
 
using namespace std;
using namespace DTLib;
 
 
 
 
class Test : public Object
{
 
 
public:
    int value;
 
 
    Test():value(0)
    {
        cout<<"Test"<<endl;
    }
    ~Test()
    {
        cout<<"~Test"<<endl;
    }
};
 
 
int main()
{
    SharedPointer<Test> sp0 = new Test();
    SharedPointer<Test> sp1 = sp0;
    SharedPointer<Test> sp2 ;
 
 
    sp2 = sp1;
 
 
   sp2->value = 20;
 
 
    cout<<sp0->value<<endl;
    cout<<sp1->value<<endl;
    cout<<sp2->value<<endl;
 
 
    cout<<(sp0 == sp2)<<endl;
 
 
    sp2.clear();
 
 
    cout<<(sp0 == sp2)<<endl;
 
 
 
 
 
 
 
 
    return 0;
}
 
 
 
 


            


            智能指针的使用军规 

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

                -不同类型的智能指针对象不能混合使用 

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



3、小结 

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

            计数机制确保多个智能指针台法的指向同—片堆空间 

            智能指针只能用于指向堆空间中的内存

            不同类型的智能指针不要混台使用 

            堆对象的生命周期由智能指针进行管理 


猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80251079
今日推荐