C++primer学习:模板编程(3):效率与灵活

shared_ptr与unique_ptr之间的明显不同是它们保存指针的策略,另一个不同是它们允许用户重载默认删除器的方式.

shared_ptr将删除器以指针的方式存储,而unique_ptr则将它作为自己类型的一部分.

[练习]:编写自己的shared_ptr类与unique_ptr类

用fuction可以接受所有的可调用对象.

#include "iostream"
#include "DebugDelete.h"
#include "functional"
 template <typename T>
 class shared_pointer
 {
     using Dtype =  function<void(T*)>;
 public:
     /**********默认构造函数****************/
     shared_pointer() = default;
     /**********接受内置指针的构造函数****************************/
     shared_pointer(T* p) :data(p), use(new int(1)),del(nullptr){}
     /************接受内置指针,以及一个删除器的构造函数******/
     shared_pointer(T* p, Dtype d) :data(p), use(new int(1)), del(new Dtype(d)){}
     /*************拷贝构造函数*****************/
     shared_pointer(const shared_pointer& p){
         data = p.data;
         use = p.use;
     }
     /**************赋值运算符**************************/
     shared_pointer& operator=(const shared_pointer& s){
         if (this != &s)//如果不是自赋值
         {
             free();
             data = p.data;
             use = p.use;
             ++*use;//递增现在的计数
         }
     }
     /**************定义*************************/
     T operator*()const{ return *data; }
     /*************定义-〉************************/
     T* operator->()const{  return  &  this->operator*(); }
     /*************析构函数*****************/
     ~shared_pointer(){ free(); }
     /************reset函数**********************/
     void reset(T* q, Dtype& d){do_ret(q, &d); }
     void reset(T* q){ do_ret(q,nullptr); }
     void reset(){ do_ret(nullptr,nullptr); }
     /****************定义size()*******************/
     size_t size()const { return (*data).size(); }
 private:
     void free(){
         if (--*use == 0)//引用计数为0
         { 
            del ? (*del)(data):delete(data);//释放data所指的内存 
             delete(use);//释放use所指的int
         }
         if (del)
             delete(del);//如果del指向某个删除器,释放内存
     }
     void do_ret(T* q, Dtype* d) {
         free();
         data = q;
         del = d;
     }
     int *use = nullptr;//指向引用计数的指针
     T* data= nullptr;//智能指针保存的普通指针
      Dtype* del = nullptr;//del用来保存删除器的信息
 };

 /************unqiue_ptr的模板************/
 template<typename T,typename Dtype = function<void (T*)>>
 class unique_pointer
 {
 public:
     unique_pointer() = default; 
      explicit unique_pointer(T* p) :data(p){}//应该定义为explicit
     unique_pointer(T*p, Dtype d) :data(p),del(d){}
     /************定义移动拷贝操作****************/
     unique_pointer(unique_pointer && u) : data(u.data), del(u.del) { u.data = nullptr; }
     /************定义移动赋值操作*************************************/
     unique_pointer& operator=(unique_pointer&& u){
         if (this != &u)
         {
             free();
             data = u.data;
             del = u.del;
             u.data = nullptr;
         }
         return *this;
     }
     /************阻止拷贝和赋值*******************/
     unique_pointer(const unique_pointer&) = delete;
     unique_pointer& operator=(const unique_pointer&) = delete;
     /************析构函数********************************/
     ~unique_pointer(){free(); }
     /**************reset********************/
     void reset(T* q = nullptr){ data = q;}
     /**************release********************/
     T* release(){ 
         auto ret = data;
         data = nullptr;
         return ret;
     }
 private:
     void free(){ del(data); }
     T* data = nullptr;//智能指针保存的指针
     Dtype del = DebugDelete();//直接保存实例化的删除器
 };

你可能感兴趣的:(C++primer学习:模板编程(3):效率与灵活)