智能指针(OSG源码摘录)

智能指针只是对指针添加引一个引用计数(_refCount).当new一个对象(即将对象赋予

ref_ptr<>变量)时_refCount加1.将ref_ptr<>变量指向其它的对象或者将其释放(超出其

生命范围,如局部变量)时,执行Referenced::unref(),_refCount会减1,此时如果

_refCount为0表明此对象已经没有引用,可删除,delete this;会调用析构函数

~Referenced(),并释放内存资源.
template<class T>
class ref_ptr
{
    public:
        typedef T element_type;

        ref_ptr() : _ptr(0) {}
        ref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); }//构造函数2
     
        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;
        }

 T* get() const { return _ptr; }

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


        T* _ptr;//类数据成员
};
void Referenced::unref()
{
 ...
 if ( ...)
 { 
  delete this;//会调用析构函数~Referenced(),并释放内存空间
 }
}

调用时:
osg::ref_ptr< osg::Group > root= new osg::Group();//新建对象,调用ref_ptr的操作

符重载函数ref_ptr& operator = (T* ptr),并将其转化为指针指向的值. 此时内存中

Group的引用计数为1.
root.get();//智能指针的成员函数

osg::ref_ptr< osg::Geode >  g= new osg::Geode();//内存中Geode的引用计数为1.
osg::ref_ptr< osg::Node >  g= new osg::Geode();//ref_ptr的=操作符重载(添加新进

的,释放原来的),上一行中的Geode的引用计数变减1,变为0,此行中新建的Node的引用计数

加1,变为1.

root->addChild( g);//智能指针指向的值的函数.此时Node的引用计数加1,变为2,因为引

用它的对象又多了一个(root).
------------------------------------------------------------
下面是一个.和->操作符两种符号能同时使用的例子:
template<class T>
class ref_ptr
{
public:
       
  ref_ptr(T* ptr) : _ptr(ptr) { }//构造函数

        T* operator->() const { return _ptr; }      //指针重载

  T* get() const { return _ptr; }

protected:
        T* _ptr;//类数据成员
};

class CA
{
public:
 void Fun()
 {
  cout<< "tm\n";
 }
};


class CA
{
public:
 void Fun()
 {
  cout<< "tm\n";
 }
};


int _tmain(int argc, _TCHAR* argv[])
{
 ref_ptr< CA> pi( new CA);
 
 pi.get();//对象本身就有.操作符
 pi->Fun();//重载的指针操作符,如果ref_ptr类中不对指针操作符进行重载,则

会报错.pi->后直接接T的成员函数,不能是pi->()或pi->()->Fun()等.
}

===========
附:指针操作符(->)重载:

重载operator->(),返回普通对象指针,称为间接(Dereferencing),可形成“智能指针

”机制(即对象->函数(),如C c; c->Fun(),这需要C类对指针操作符进行重载)。这样

方便操作,也可不用。对于obj->member;,operator ->为一元后缀运符,可作两种解释


①如obj为指针,将寻找紧随其后的类成员(或函数)标识符,找不到就出错,这也是最常

见的用法。
②如obj为(定义的智能指针)对象,将解释为(obj.operator->())->member。若obj类未

重载operator->()则出错;当重载了X operator ->()时,如果返回类型X为指针,则进入

①状态;如果返回值类型仍为对象,再进入②状态,判断是否可循环。

返回值应该为两种:①指针,并找到成员标志符;②定义了operator->()的对象,将循环

迭代。否则出错。
具体示例见于《C++ Primer》14.6节与《C++ Programming Language》11.10章节。
如上面代码中的pi->Fun();即相当于是(pi.operator->())->Fun()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值