VTK之引用计数详解

来源:互联网 发布:java 接口 抽象类 编辑:程序博客网 时间:2024/06/09 21:43

内存管理

  内存管理在大型的工程中是非常重要的内容,如果不能有效地管理内存,比如申请的内存没有及时释放,将严重影像到应用程序的执行效率,甚至可能带来不可预知的崩溃。C++语言中并没有提供高级的内存管理与垃圾回收机制,通常都是手工管理。这对于简单的程序而言可轻松完成,但在许多复杂情况下就会疲于应付。例如当一个内存对象(可以看作一个指针)被多个对象引用,删除任何一个对象,都可能
影像到其他对象,因此VTK中用引用计数和智能指针来解决这个问题。

引用计数

  引用计数就是每一个对象中维护一个引用计数的变量,表示当前对象被多少个对象引用。当一个对象被另外一个对象引用时,该对象的引用计数加1;只要有其他对象引用该对象(引用计数不为0),那么该对象就会一直存在。当一个对象取消对该对象的引用时,该对象的引用计数减1。当引用计数为0时,程序则销毁该对象。
  VTK中实现引用计数的类是vtkObjectBase,它是VTK类共同的基类。vtkObjectBase中定义了一个ReferenceCount变量,该变量记录了引用计数。当一个vtkObjectBase及其子类对象创建时,ReferenceCount即被初始化为1;

vtkObjectBase::vtkObjectBase(){this->ReferenceCount = 1;}

   查看vtkObjectBase的源代码可以发现,vtkObjectBase的构造函数、析构函数、拷贝构造函数以及“=”操作符都被声明为protected类型,因此不能显式地构造和销毁vtkObjectBase及其子类对象。vtkObjectBase定义了一个静态函数New(),用于生成vtkObjectBase对象。New()函数中调用了构造函数来生成一个对象,并在构造函数中初始化引用计数为1;生成一个vtkObjectBase及其子类对象后,多数情况下可能被其他对象引用。此时需要调用Register()函数来实现引用计数加1。而Unregister()函数则实现引用计数减1,并检查引用计数的对象。当引用计数为0时,自动销毁该对象。
  对于New()的对象,一定要通过Delete()对象来删除。Delete()函数并非直接删除对象,而是通过调用Unregister对象来将引用计数减1;

vtkCamera *camera = vtkCamera::New(); //引用计数是1renderer.SetActiveCamera(camera);  //引用计数是2renderer->Delete();  //引用计数是1camera->Delete();    //引用计数是0,并销毁

vtkRenderer::SetActiveCamera()函数的代码如下:

这里写图片描述
  在SetActiveCamera()函数里,如果当前已设置ActiveCamera,则先调用UnRegister该对象,引用计数减1。然后调用Register()函数cam对象引用计数加1。