关闭

两种智能指针-RAII智能指针和引用计数智能指针

标签: 智能指针引用计数
231人阅读 评论(0) 收藏 举报
分类:

两种智能指针-RAII智能指针和引用计数智能指针

RAII简介

RAII的全称是:Resource Acquisition Is Initialization 也就是“资源获取就是初始化”。就像内存分配是在变量初始化的时候分配的;比如,当程序结束时,系统会自动释放程序所使用的资源;函数传值时,当函数调用结束,该值也将消亡。

RAII智能指针代码参考

#include <iostream>

#define SAFE_DELETE(ptr) if(nullptr!=ptr){delete ptr;ptr=nullptr;}//安全delete

template<typename T>class SmartPtr{
public:
    typedef T element_type;

    explicit SmartPtr(T * ptr=nullptr):m_ptr(ptr){}

    SmartPtr(SmartPtr<T> & ptr):m_ptr(ptr.release()){}

    inline T * release(){
        T * tmp=m_ptr;
        SAFE_DELETE(m_ptr);
        return m_ptr;
    }

    SmartPtr<T>& operator=(SmartPtr<T>& ptr){
        if(&ptr != this){
            SAFE_DELETE(m_ptr);
            m_ptr=ptr.release();
        }
        return *this;
    }

    SmartPtr<T>& operator= (T * ptr){
        if(ptr!=ptr.get()){
            SAFE_DELETE(m_ptr);
            m_ptr=ptr.release();
        }
        return *this;
    }

    ~SmartPtr(){SAFE_DELETE(m_ptr);}

    inline T * operator->(){return m_ptr;}
    inline T & operator*(){return *m_ptr;}

    inline void reset(T * ptr=nullptr){
        SAFE_DELETE(m_ptr);
        m_ptr=ptr;
    }

    inline T * get()const{return m_ptr;}

private:
    T * m_ptr;
};

int main(){
    SmartPtr<int>ptr(new int(234));
    std::cout<<*ptr<<std::endl;
    std::cout<<*ptr.get()<<std::endl;
    return 0;
}

第二种写法:

#include <iostream>

template<typename T>
inline void SafeDelete(T*& ptr) {
    if (ptr != nullptr) {
        delete ptr;
        ptr = nullptr;
    }
}

template<typename T>
class SmartPtr {
public:
    SmartPtr() :m_ptr(nullptr) {}
    SmartPtr(T * ptr):m_ptr(ptr){}
    SmartPtr(const SmartPtr<T> & other) = delete;
    template<typename Tx>SmartPtr(const SmartPtr<Tx> & other) = delete;
    SmartPtr(SmartPtr<T>&&other){
        T *ptr = other.m_ptr;
        other.m_ptr = m_ptr;
        m_ptr = ptr;
    }
    ~SmartPtr() { SafeDelete(m_ptr); }
    SmartPtr & operator=(const SmartPtr<T>& other) = delete;
    template<typename Tx>SmartPtr & operator=(const SmartPtr<Tx>&other) = delete;
    SmartPtr & operator=(const SmartPtr<T>&&other) {
        if (this != &other) {
            T *ptr = other.m_ptr;
            other.m_ptr = m_ptr;
            m_ptr = ptr;
        }
    }
    inline T & operator*() {
        return *m_ptr;
    }
    inline T * operator->() {
        return m_ptr;
    }
    inline const T & operator*()const {
        return *m_ptr;
    }
    inline const T * operator->()const {
        return m_ptr;
    }
    inline T * release(){
        T * bk = m_ptr;
        m_ptr = nullptr;
        return bk;
    }
    inline void reset(T * ptr = nullptr) {
        SafeDelete(m_ptr);
        m_ptr = ptr;
    }
    inline T * get() { return m_ptr; }
    inline const T * get()const { return m_ptr; }
private:
    T * m_ptr;
};

struct My {
    int data = 100;
};

int main() {
    SmartPtr<int> ptr(new int(2342));
    std::cout << *ptr << std::endl;
    SmartPtr<My> ptrx(new My);
    std::cout << ptrx->data << std::endl;
    std::cin.get();
    return 0;
}

引用计数版本参考代码

引用计数使用到了代理模式的相关知识:参考
http://baike.baidu.com/view/2645890.htm

#include <iostream>
#include <windows.h>

#define SAFE_DELETE(ptr) if(ptr!=nullptr){delete ptr;ptr=nullptr;}

class RefCount{
public:
    RefCount():m_count(0){}
    ~RefCount(){}
    unsigned long AddRef(){return InterlockedIncrement(reinterpret_cast<long *>(&m_count));}
    unsigned long Release(){return InterlockedDecrement(reinterpret_cast<long *>(&m_count));}
    inline void Reset(){m_count=0;}
private:
    unsigned long m_count;
};

template<typename T>class SmartPtr{
public:
    typedef T element_type;

    explicit SmartPtr():m_ptr(nullptr),m_counter(new RefCount){m_counter->AddRef();}

    SmartPtr(T * ptr):m_ptr(ptr),m_counter(new RefCount){m_counter->AddRef();}

    SmartPtr(const SmartPtr<T>& ptr)=delete;

    SmartPtr(SmartPtr<T>&& ptr):m_ptr(ptr.m_ptr),m_counter(ptr.m_counter){
        ptr.m_ptr=nullptr;
        ptr.m_counter=nullptr;
    }

    SmartPtr<T>& operator=(const SmartPtr<T>& ptr)=delete;

    SmartPtr<T>& operator=(SmartPtr<T>&& ptr){
        if(m_counter && m_counter->Release()==0){
            SAFE_DELETE(m_ptr);
            SAFE_DELETE(m_counter);
        }
        m_ptr=ptr.m_ptr;
        ptr.m_ptr=nullptr;
        m_counter=ptr.m_counter;
        ptr.m_counter=nullptr;
        return *this;
    }

    SmartPtr<T>& operator=(T * ptr){
        if(ptr != m_ptr){
            if(m_counter && m_counter->Release()==0){
                SAFE_DELETE(m_ptr);
                m_counter->Reset();
            }
            m_ptr=ptr;
            m_counter->AddRef();
        }
    }

    inline T * get()const{return m_ptr;}

    inline T & operator*(){return *m_ptr;}

    inline T * operator->(){return m_ptr;}

    inline void swap(SmartPtr<T> & ptr){
        T * tmp=ptr.m_ptr;
        RefCount * rtmp=ptr.m_counter;
        ptr.m_ptr=m_ptr;
        ptr.m_counter=m_counter;
        m_ptr=tmp;
        m_counter=rtmp;
    }

    inline T * release(){
        T * tmp=m_ptr;
        m_ptr=nullptr;
        return m_ptr;
    }

private:
    RefCount * m_counter;
    T * m_ptr;
};

int main(){
    SmartPtr<int>ptr(new int(2432));
    std::cout<<*ptr<<std::endl;
    std::cout<<*ptr.get()<<std::endl;
    return 0;
}

关于InterlockedIncrement和InterlockedDecrement参考:
http://baike.baidu.com/view/6235756.htm

版本2:

#include <iostream>
#include <Windows.h>

template<typename T>
inline void SafeDelete(T*& ptr) {
    if (ptr != nullptr) {
        delete ptr;
        ptr = nullptr;
    }
}

class RefCounter {
public:
    RefCounter():m_cnt(0){}
    ~RefCounter() {}
    std::size_t RefAdd() { return InterlockedIncrement(&m_cnt); }
    std::size_t Release() { return InterlockedDecrement(&m_cnt); }
    std::size_t getcnt() { return m_cnt; }
    void reset() { m_cnt = 0; }
private:
    size_t m_cnt;
};

template<typename T>
class SmartPtr {
public:
    SmartPtr() :m_ptr(nullptr) ,m_counter(new RefCounter){
        m_counter->RefAdd();
    }
    SmartPtr(T * ptr) :m_ptr(ptr), m_counter(new RefCounter) {
        m_counter->RefAdd();
    }
    SmartPtr(const SmartPtr<T>& other) = delete;
    template<typename Tx>SmartPtr(const SmartPtr<Tx>&other) = delete;
    SmartPtr(SmartPtr<T>&&other) :m_ptr(other.m_ptr),m_counter(other.m_counter){
        other.m_ptr = nullptr;
        other.m_counter = nullptr;
    }
    ~SmartPtr() {
        if (m_counter != nullptr && m_counter->Release() == 0) {
            SafeDelete(m_ptr);
            SafeDelete(m_counter);
        }
    }
    SmartPtr & operator=(const SmartPtr<T>& other) = delete;
    template<typename Tx>SmartPtr & operator=(const SmartPtr<Tx>& other) = delete;
    SmartPtr & operator=(SmartPtr<T>&&other) {
        if (&other != this) {
            if (m_counter != nullptr && m_counter->Release() == 0) {
                SafeDelete(m_ptr);
                SafeDelete(m_counter);
            }
            m_ptr = other.m_ptr;
            m_counter = new RefCounter;
            m_counter->RefAdd();
        }
    }
    T * relaese() {
        if (m_counter != nullptr && m_counter->Release() == 0) {
            SafeDelete(m_ptr);
            SafeDelete(m_counter);
        }
        m_ptr = nullptr;
        m_counter = nullptr;
    }
    void reset(T * ptr = nullptr) {
        if (m_counter != nullptr && m_counter->Release() == 0) {
            SafeDelete(m_ptr);
            SafeDelete(m_counter);
        }
        m_ptr = ptr;
        m_counter = new RefCounter;
        m_counter->RefAdd();
    }
    T & operator*() { return *m_ptr; }
    const T & operator*()const { return *m_ptr; }
    T*operator->() { return m_ptr; }
    const T*operator->()const { return m_ptr; }
private:
    T * m_ptr;
    RefCounter * m_counter;
};

struct My {
    int data = 1000;
};

int main() {
    SmartPtr<My> ptr(new My);
    std::cout << ptr->data << std::endl;
    SmartPtr<double> ptrx(new double(24.2));
    std::cout << *ptrx << std::endl;
    std::cin.get();
    return 0;
}

注:代码尚有缺点。

转载请注明出处

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:17504次
    • 积分:408
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条