共享型智能指针的实现share_pointer

智能指针是一个类,它产生的是一个类对象,而不是一个原生的指针对象,但是为了减少类对象与针对对象使用的差异性,所以share_ptr类故意重载了两种常见的指针操作符: *和->。从而share_ptr与普通指针使用方式一样。简言之,就是share_ptr生成的一个包含类型指针容器对象,它封装了指针对象,对指针对象负全责,包括生成、释放等。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象

  • 下面代码为share_pointer的实现,包括:
    • 默认构造函数
    • 显式定义的自定义构造函数
    • 拷贝构造函数
    • 移动构造函数
    • 拷贝赋值函数
    • 移动赋值函数
    • *运算符
    • ->运算符
    • 三个版本的reset函数
  • 计数变量设为指针,主要是因为计数是共有的,这样一方面可以节省内存,另一方面可以达到管理共有变量的目的
  • destroy函数delete指针时不调用删除器
  • 删除器为一个可调用模板,在调用函数中可以用function定义其模式
#ifndef SHAREPOINTER_H
#define SHAREPOINTER_H

#include "DebugDelete.h"
#include 
#include 
//1.模板成员函数知道使用时编译器才去编译
template<typename T>class share_pointer
{
public:

    //默认构造函数
    share_pointer(){} 


    //显式定义构造函数,传递指针管理类型和删除器对象两个形参
    explicit share_pointer(T *t, std::function<void(T*)> d = DebugDelete()):t(t),count(new size_t(1)),Deleter(d){}


    //拷贝构造函数
    share_pointer(share_pointer &sp):count(sp.count),t(sp.t),Deleter(sp.Deleter){
        std::cout << "copy" << std::endl;
        ++*count;
    }


    //移动构造函数,share_pointer m(share_pointer(new int(30)))调用移动构造函数,若无,则调用拷贝构造函数
    share_pointer(share_pointer &&sp):count(sp.count),t(std::move(sp.t)),Deleter(std::move(sp.Deleter)){
        std::cout << "moving" << std::endl;
        sp.t = nullptr;
    }


    //赋值构造函数
    share_pointer &operator=(share_pointer &sp);


    //返回指针指向的值
    T& operator*() const {return *t;}


    //重载->
    T* operator->() const {return &this->operator*();}

    //reset
    void reset(){
        deconstructor();
    }

    void reset(T* p){
        if (t)
        {
            deconstructor();
            t = p;
            count = new size_t(1);
        }
    }

    void reset(T* p,std::function<void(T*)> d){
            reset(p);
            Deleter = d;
    }



private:

    std::size_t *count;//6.计数为不同对象的公共变量,固定义一个指针,指向共有内存

    T *t ;

    std::function<void (T*)> Deleter;

    void deconstructor();
};

template<typename T> 
inline void share_pointer::deconstructor(){
    if(t)
    {
        --*count;
        if (*count == 0)
        {
            Deleter(t);
            delete count;
        }
    }
    t = nullptr;
    count = nullptr;
}

template<typename T>
inline share_pointer &share_pointer::operator=(share_pointer &sp){
    ++(*sp.count);
    deconstructor();
    count = sp.count;
    t = sp.t;
    Deleter = sp.Deleter;
    return *this;
}

#endif
  • 下面代码为删除器代码
#ifndef DEBUGDELETE_H
#define DEBUGDELETE_H
#include 
 class DebugDelete
{
public:
    DebugDelete(std::ostream &s = std::cerr):os(s){}  //流无法被拷贝
    template<typename T> void operator()(T* t)const
    {
        os << "deleting ptr" << std::endl;
        //std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
        delete t;
        //std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
    }
private:
    std::ostream &os;//流无法被拷贝
 };
#endif
  • 下面为主函数
#include "DebugDelete.h"
#include 
#include "share_pointer.h"
#include 
#include 
#include 
#include 

int _tmain(int argc, _TCHAR* argv[])
{
    share_pointer<int> p(new int(20));
    share_pointer<int> s(new int(30));
    share_pointer<int> q(s);
    s = p;
    share_pointer<int> m(share_pointer<int>(new int(30)));
    int mm = *m;
    share_pointer<std::string> n(share_pointer<std::string>(new std::string("hello")));
    n.reset();
    m.reset(new int(32));
    p.reset(new int(43),DebugDelete());

    return 0;
}

你可能感兴趣的:(C++程序)