OSG的垃圾回收机制

为了让OSG的开发者更加专注与功能开发远离c++最最烦心的指针(当然指针也是c++如此牛掰的根源),OSG也使用了类似其他一些高级语言的GC.

OSG的垃圾回收主要是包含两个方面: osg::ref_ptr<>-自动回收内存 和 osg::Referenced-引用计数类.

osg::ref_ptr<>

osg::ref_ptr<>既可以向c++的普通指针一样使用(operator*(),operator->,operator=()),也有它的高级功能(operator==(), operator!=() , operator!(),valid(),release()).

类似普通指针的几个方法和operator==(), operator!=() , operator!()就不介绍了.

valid()和some_ptr!=NULL是一样的.判断指针是否为空

release()这个方法是返回一个智能指针指向的内容,主要作用:因为c++局部变量的作用域是两个大括号之间,当程序运行过大括号时,osg::ref_ptr<>会自动释放其指向的内存空间,所以如下方法:

作者:kjwang
链接:https://zhuanlan.zhihu.com/p/37816503
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

#include <osg/ref_ptr>
#include <osg/Referenced>
#include <iostream>
class MonitoringTarget : public osg::Referenced
{
  public:
  MonitoringTarget( int id ) : _id(id)
  { std::cout << "Constructing target " << _id << std::endl; }
  protected:
  virtual ~MonitoringTarget()
  { std::cout << "Destroying target " << _id << std::endl; }
  int _id;
};
osg::ref_ptr<MonitoringTarget> target = new MonitoringTarget(0);
std::cout << "Referenced count before referring: "<< target->referenceCount() << std::endl;
osg::ref_ptr<MonitoringTarget> anotherTarget = target;
std::cout << "Referenced count after referring: "<< target->referenceCount() << std::endl;
for ( unsigned int i=1; i<5; ++i )
{
  osg::ref_ptr<MonitoringTarget> subTarget = new MonitoringTarget(i);
}

打印结果:

而我们想在一个函数中返回其中一个局部osg::ref_ptr<>变量所指向的内容时,

MonitoringTarget* createMonitoringTarget( unsigned int id )
{
   osg::ref_ptr<MonitoringTarget> target = new MonitoringTarget(i);
   return target.get();
}

就会发现上述代码得不到内容.

此时我们就会用到release()函数了.

MonitoringTarget* createMonitoringTarget( unsigned int id )
{
osg::ref_ptr<MonitoringTarget> target = new MonitoringTarget(i);
return target.release();
}

release()的作用就是禁止智能指针释放其所指向的内容,且返回一个c++的普通指针.

注意: 接这个函数的返回值时必须用新的osg::ref_ptr<>包装一下,这样就可以正常使用了.

osg::Referenced

osg::Referenced类是osg中所有成员的base class.它的方法主要是 ref(),unref(),referenceCount().

ref().是在这个类被osg::ref_ptr<>包装时,就是把计数器+1.

unref():包装了这个类的osg::ref_ptr<>被释放时,计数器-1.当为0时,就是回收这块内存空间.

注意:osg::Referenced类的析构函数是protected类型的.所以不可以在局部变量中使用以下代码:


 

osg::Node node;//osg::node间接继承自osg::Referenced     !!!!错误代码!!!!

注意:既然是引用计数,一定要知道它的最大的不足就是循环引用.

上图是两种循环引用的情况,自循环和相互引用.这都是在使用智能指针(引用计数形)一定要注意的地方.

本文转自:https://www.zhihu.com/column/c_187589347

猜你喜欢

转载自blog.csdn.net/danshiming/article/details/113795085