智能指针(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()。
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()。
相关文章推荐
- [osg]源码分析:OSG中的智能指针osg::ref_ptr
- [osg]源码分析:OSG中的智能指针osg::ref_ptr
- [osg]源码分析:OSG中的智能指针osg::ref_ptr
- 不可不表的OSG智能指针之强指针与弱指针
- OSG中引用计数与智能指针实现原理
- 智能指针之scoped_ptr源码剖析
- shared_ptr智能指针源码剖析
- 不可不表的OSG智能指针之强指针与弱指针 《转载》
- C++智能指针auto_ptr源码完全解析---以微软auto_ptr为例来探讨auto_ptr的用法
- shared_ptr智能指针源码剖析
- 智能指针之scoped_ptr源码剖析
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- 智能指针auto_ptr源码
- shared_ptr智能指针源码剖析
- ReactNative4Android源码分析1: JNI智能指针之介绍篇
- C++ 智能指针(shared_ptr/weak_ptr)源码分析
- 【C++】Android (Light)RefBase-sp-wp引用计数-智能指针源码分析
- 智能指针auto_ptr源码剖析
- OSG中的智能指针
- shared_ptr智能指针源码剖析