您的位置:首页 > 其它

智能指针(OSG源码摘录)

2010-07-27 15:58 489 查看
智能指针只是对指针添加引一个引用计数(_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()。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: