zoukankan      html  css  js  c++  java
  • 根据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
  • 相关阅读:
    iOS 网络优化--页面返回的时候取消网络请求
    iOS 内存管理
    realm数据库使用
    KNN 算法分类电影类型
    sklearn库学习之01
    Python 生成4位验证码图片
    Python——读写Excel文件
    KNN--用于手写数字识别
    Python基础学习-'module' object has no attribute 'urlopen'解决方法
    swift_通知的使用
  • 原文地址:https://www.cnblogs.com/coolbear/p/3780071.html
Copyright © 2011-2022 走看看