VTK内存管理与智能指针

vtk的vtkSmartPointer保证你只要在各个地方都用这个智能指针创建对象,就不会有内存泄漏。

vtkSmartPointer可以理解成STL的std::shared_ptr但是又不同。

vtkSmartPointer的引用计数器变量存储在被管理的动态对象里,而std::shared_ptr所管理的动态对象不负责引用计数,引用计数是std::shared_ptr自己的责任,std::shared_ptr通过复制控制来实现引用计数。

	auto points = vtkPoints::New();//原始指针,需要手动释放,否则内存泄漏
	vtkNew points1;//使用引用计数
	vtkSmartPointer points2 = vtkSmartPointer::New();//使用引用计数

但是,VTK的接口传递都是原始指针 :

//这里是指针接口
unsigned long AddObserver(unsigned long event, vtkCommand *, float priority=0.0f);
//这里是智能指针接口
vtkSmartPointer boxCallback = vtkSmartPointer::New();
//这里是智能指针对象
box3D->AddObserver(vtkCommand::EndInteractionEvent, boxCallback);

vtkSmartPointer会增加减少引用计数,但是原始指针绕过了vtkSmartPointer的复制控制,从而让引用计数丢失。那就意味着AddObserver里面也会增加减少引用计数。那就说明这两个引用计数的计数器变量不在vtkSmartPointer那里,而在被指的原始对象里。

void vtkObjectBase::RegisterInternal(vtkObjectBase*, vtkTypeBool check)
{
  // If a reference is available from the garbage collector, use it.
  // Otherwise create a new reference by incrementing the reference
  // count.
  if(!(check &&
       vtkObjectBaseToGarbageCollectorFriendship::TakeReference(this)))
  {
    this->ReferenceCount++;
  }
}

正如上面的代码,AddObserver的时候会调用vtkCommand的register方法,这个vtkCommand其实是vtkObjectBase派生来的。

vtkObjectBase实现引用计数,每个vtkObjectBase对象都有一个this->ReferenceCount成员。

这就解释了vtk的内存引用计数原理:

1 每一个vtk对象都是一个vtkObjectBase对象;

2 这个对象自带引用计数器;

3 这个引用计数器一部分由vtkSmartPointer来改变;

4 这个引用计数器一部分由其他类似AddObserver这样的函数内部调用vtkObjectBase的register方法来改变;

5 以上4个方面共同完成引用计数的功能。

6 之所以接口用原始指针,是因为简单、避免到处都是vtkSmartPointer的构造、析构成本;减少编译成本;降低接口复杂度;

你可能感兴趣的:(VTK/ITK)