[osg]源码分析:OSG中的智能指针osg::ref_ptr

探究一下osg中的智能指针:osg::ref_ptr。

一、首先注意,智能指针是个模板类(不要以为理解了这句话)。比如这样一个定义:

osg::ref_ptr pArray = new osg::Vec3Array;

这里,pArray本质上是一个ref_ptr对象(并非是指针),而之所以可以将new返回的指针赋给他是因为osg::ref_ptr重写了赋值操作符(关于赋值操作符的重写原则见effective c++)。而之气以可以对pArray解引用作*操作,是因为osg::ref_ptr重写了*操作符。

二、对赋值操作符的重写有两个版本

1.版本1是将ref_ptr&赋给一个ref_ptr对象

        ref_ptr& operator = (const ref_ptr& rp)
        {
            assign(rp);
            return *this;
        }

assign进行了维护引用计算的操作:

        template void assign(const ref_ptr& rp)
        {
            if (_ptr==rp._ptr) return;
            T* tmp_ptr = _ptr;
            _ptr = rp._ptr;
            if (_ptr) _ptr->ref();      // 对右操作数rp引用加1,同时左操作数引用减1
            // 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();
        }

赋值时,两个ref_ptr的模板可以不同(只限这个版本的重载)。

2.版本2是将指向模板的指针赋给ref_ptr

        inline ref_ptr& 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;
        }

这个版本较长使用。

这里可以看到,如果想用智能指针,就必须要有引用计数,即模板类必须要有ref方法,在osg中就体现在必须要继承自osg::Reference。例如osg::Vec3,他就不可以作为ref_ptr的模板。

三、重写解引用操作符

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

这里_ptr是指向模板T的指针,如此便返回了_ptr所指对象的引用。

四、重载箭头操作符

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

这里箭头操作符得到的是指向T的指针,故而,上列pArray->返回的是指向osg::Vec3Array的指针,然后可以调用Vec3Array的方法。

五、重载比较操作符

        bool operator == (const ref_ptr& rp) const { return (_ptr==rp._ptr); }
        bool operator == (const T* ptr) const { return (_ptr==ptr); }
        friend bool operator == (const T* ptr, const ref_ptr& rp) { return (ptr==rp._ptr); }

        bool operator != (const ref_ptr& rp) const { return (_ptr!=rp._ptr); }
        bool operator != (const T* ptr) const { return (_ptr!=ptr); }
        friend bool operator != (const T* ptr, const ref_ptr& rp) { return (ptr!=rp._ptr); }

        bool operator < (const ref_ptr& rp) const { return (_ptr 
 

你可能感兴趣的:([osg]源码分析:OSG中的智能指针osg::ref_ptr)