根据OSG中的ref_ptr和Reference简化的智能指针

main.cpp测试代码

#include "TestSmartPointer"
void fun()
{
    SP<TestSmartPointer> sp1=new TestSmartPointer("A");
    SP<TestSmartPointer> sp2=sp1;
    sp1=sp2;
}
void main()
{
    fun();
    //system("pause");
}

TestSmartPointer头文件

#pragma once

#include "Referenced"
#include "SmartPointer"

#include <string>

class TestSmartPointer : public Referenced
{
    public:
        inline TestSmartPointer(std::string name):Referenced(),_name(name) {}
    protected:

        virtual ~TestSmartPointer() {}
        
        std::string _name;
};

Referenced计数器

#ifndef REFERENCED
#define REFERENCED 1

#include <iostream>
using namespace std;

/** Base class from providing referencing counted objects.*/
class Referenced
{
    public:
        Referenced() { _refCount=0; }
        Referenced(const Referenced&) { _refCount=0; }
        inline Referenced& operator = (const Referenced&) { return *this; }

        /** Increment the reference count by one, indicating that 
            this object has another pointer which is referencing it.*/
        inline void ref() const;
        
        /** Decrement the reference count by one, indicating that 
            a pointer to this object is referencing it.  If the
            reference count goes to zero, it is assumed that this object
            is no longer referenced and is automatically deleted.*/
        inline void unref() const;
        
        /** Decrement the reference count by one, indicating that 
            a pointer to this object is referencing it.  However, do
            not delete it, even if ref count goes to 0.  Warning, unref_nodelete() 
            should only be called if the user knows exactly who will
            be resonsible for, one should prefer unref() over unref_nodelete() 
            as the later can lead to memory leaks.*/
        inline void unref_nodelete() const;
        
        /** Return the number pointers currently referencing this object. */
        inline int referenceCount() const { return _refCount; }

    protected:
        virtual ~Referenced()
        {
            if (_refCount>0)
            {
                cout<<"Warning: deleting still referenced object "<<this<<" of type '"<<typeid(this).name()<<"'"<<std::endl;
                cout<<"the final reference count was "<<_refCount<<", memory corruption possible."<<std::endl;
            }
        }
        mutable int  _refCount;
};


inline void Referenced::ref() const
{
    ++_refCount;
}

inline void Referenced::unref() const
{
    bool needDelete = false;
    --_refCount;
    needDelete = _refCount<=0;

    if (needDelete)
    {
        delete this;
    }
}
inline void Referenced::unref_nodelete() const
{
    --_refCount;
}

#endif

SmartPointer智能指针模板类

#ifndef SMART_POINTER
#define SMART_POINTER 1

/** Smart pointer for handling referenced counted objects.*/
template<class T>
class SP
{
    public:
        typedef T element_type;

        SP() :_ptr(0L) {}
        SP(T* t):_ptr(t)              { if (_ptr) _ptr->ref(); }
        SP(const SP& rp):_ptr(rp._ptr)  { if (_ptr) _ptr->ref(); }
        ~SP()                           { if (_ptr) _ptr->unref(); _ptr=0; }

        inline SP& operator = (const SP& rp)
        {
            if (_ptr==rp._ptr) return *this;
            T* tmp_ptr = _ptr;
            _ptr = rp._ptr;
            if (_ptr) _ptr->ref();
            // unref second to prevent any deletion of any object which might
            // be referenced by the other object. i.e rp is child of the
            // original _ptr.
            if (tmp_ptr) tmp_ptr->unref();
            return *this;
        }

        inline SP& operator = (T* ptr)
        {
            if (_ptr==ptr) return *this;
            T* tmp_ptr = _ptr;
            _ptr = ptr;
            if (_ptr) _ptr->ref();
            // unref second to prevent any deletion of any object which might
            // be referenced by the other object. i.e rp is child of the
            // original _ptr.
            if (tmp_ptr) tmp_ptr->unref();
            return *this;
        }

        // comparison operators for SP.
        inline bool operator == (const SP& rp) const { return (_ptr==rp._ptr); }
        inline bool operator != (const SP& rp) const { return (_ptr!=rp._ptr); }
        inline bool operator < (const SP& rp) const { return (_ptr<rp._ptr); }
        inline bool operator > (const SP& rp) const { return (_ptr>rp._ptr); }

        // comparison operator for const T*.
        inline bool operator == (const T* ptr) const { return (_ptr==ptr); }
        inline bool operator != (const T* ptr) const { return (_ptr!=ptr); }
        inline bool operator < (const T* ptr) const { return (_ptr<ptr); }
        inline bool operator > (const T* ptr) const { return (_ptr>ptr); }


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

        inline const T& operator*() const { return *_ptr; }

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

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

        inline bool operator!() const   { return _ptr==0L; }

        inline bool valid() const       { return _ptr!=0L; }
        
        inline T* get() { return _ptr; }

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

        /** take control over the object pointed to by SP, unreference but do not delete even if ref count goes to 0,
          * return the pointer to the object.
          * Note, do not use this unless you are 100% sure your code handles the deletion of the object correctly, and
          * only use when absolutely required.*/
        inline T* take() { return release();}

        inline T* release() { T* tmp=_ptr; if (_ptr) _ptr->unref_nodelete(); _ptr=0; return tmp;}

    private:
        T* _ptr;
};

#endif
原文地址:https://www.cnblogs.com/coolbear/p/3780071.html