VTK源码阅读--从vtkObjectBase开始

vtkObjectBase类

        vtkObjectBase类是所有引用计数类的基类,其内部使用了原子(atomic)操作的引用计数ReferenceCount和vtkWeakPointerBase类型的WeakPointers(弱指针列表)

        vtkObjectBase类执行引用计数:只要另一个对象使用它们,引用计数的对象就存在。一旦对引用计数对象的最后一个引用被删除,该对象将自发销毁。

        vtkObjectBase类将构造函数和析构函数访问权限设置为protected,只供派生类的New方法和Delete方法使用;由于外部不可以访问构造函数和析构函数,则就不会在堆栈外自动生成vtkObjectBase类对象;

        

        为什么要使用引用计数

        在程序中,一个值可能被用于多个对象,出现多个相同内容的对象,那么在程序中没必要将这个值或者对象存储很多次。能想到的办法是只保持一个拥有值的对象,其他对象共享这个值对象的副本;引用计数就是在做这个事情,它允许多个有相同值的对象共享这个值,构建一个简单的垃圾回收机制,只要其他对象引用某对象(对象O),对象O就会增加一个引用计数,随着其他对象的析构消亡,对象O就会减少一个引用计数,如果最后引用对象O的对象移除,对象O就会自动析构。

        VTK里使用引用计数的好处是,可以实现数据之间的共享而不用复制,从而达到节省内存的目的;

成员变量

  vtkAtomicInt32 ReferenceCount;
  vtkWeakPointerBase **WeakPointers;

        WeakPointers用于记录弱指针列表;

方法

        获取类名的字符串:

virtual const char* GetClassNameInternal() const { return "vtkObjectBase"; }
const char* GetClassName() const;

        判断字符串描述的类型与当前类类型是否相同:

static vtkTypeBool IsTypeOf(const char* name);
virtual vtkTypeBool IsA(const char* name);

        判断输入类型与基类的代数:

static vtkIdType GetNumberOfGenerationsFromBaseType(const char* name);
virtual vtkIdType GetNumberOfGenerationsFromBase(const char* name);

        创建和释放:

        New用于创建对象,Delete用于释放对象;一般情况下不要使用FastDelete;

virtual void Delete();
virtual void FastDelete();
static vtkObjectBase* New() {
    vtkObjectBase* o = new vtkObjectBase;
    o->InitializeObjectBase();
    return o;
}

void InitializeObjectBase();

        打印日志:

void Print(ostream& os);
virtual void PrintSelf(ostream& os, vtkIndent indent);
virtual void PrintHeader(ostream& os, vtkIndent indent);
virtual void PrintTrailer(ostream& os, vtkIndent indent);

        Print调用了PrintHeader、PrintSelf和PrintTrailer;

void vtkObjectBase::Print(ostream& os) {
  vtkIndent indent;

  this->PrintHeader(os, vtkIndent(0));
  this->PrintSelf(os, indent.GetNextIndent());
  this->PrintTrailer(os, vtkIndent(0));
}

        PrintHeader用于打印当前类名:

void vtkObjectBase::PrintHeader(ostream& os, vtkIndent indent) {
  os << indent << this->GetClassName() << " (" << this << ")\n";
}

        PrintSelf用于打印引用计数:

void vtkObjectBase::PrintSelf(ostream& os, vtkIndent indent) {
  os << indent << "Reference Count: " << this->ReferenceCount << "\n";
}

        PrintTrailer用于打印每个层次的缩进(空格字符串):

void vtkObjectBase::PrintTrailer(ostream& os, vtkIndent indent) {
  os << indent << "\n";
}

        vtkIndent类使用了一个含有40个空格的全局静态变量blanks,vtkIndent重载了operator<<,可以根据Indent在blanks定位字符串开始位置;

ostream& operator<<(ostream& os, const vtkIndent& ind) {
  os << blanks + (VTK_NUMBER_OF_BLANKS - ind.Indent);
  return os;
}

        引用计数的核心接口

        下面是对外使用的接口:

virtual void Register(vtkObjectBase* o);
virtual void UnRegister(vtkObjectBase* o);
int GetReferenceCount() { return this->ReferenceCount; }
void SetReferenceCount(int);

        这里需要注意的是,如果是使用下面的代码New了一个指针时,之后调用GetReferenceCount函数后,得到的结果不一定为1;

T* ptr = vtk**::New();

        Register和UnRegister是调用了内部的protected函数:

virtual void RegisterInternal(vtkObjectBase*, vtkTypeBool check);
virtual void UnRegisterInternal(vtkObjectBase*, vtkTypeBool check);
virtual void ReportReferences(vtkGarbageCollector*);

具体实现如下:

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++;
  }
}

//----------------------------------------------------------------------------
void vtkObjectBase::UnRegisterInternal(vtkObjectBase*, vtkTypeBool check){
  // If the garbage collector accepts a reference, do not decrement
  // the count.
  if (check && this->ReferenceCount > 1 &&
    vtkObjectBaseToGarbageCollectorFriendship::GiveReference(this)) {
    return;
  }

  // Decrement the reference count, delete object if count goes to zero.
  if (--this->ReferenceCount <= 0) {
    // Clear all weak pointers to the object before deleting it.
    if (this->WeakPointers) {
      vtkWeakPointerBase** p = this->WeakPointers;
      while (*p) {
        vtkObjectBaseToWeakPointerBaseFriendship::ClearPointer(*p++);
      }
      delete[] this->WeakPointers;
    }
    delete this;
  }
  else if (check)
  {
    // The garbage collector did not accept the reference, but the
    // object still exists and is participating in garbage collection.
    // This means either that delayed garbage collection is disabled
    // or the collector has decided it is time to do a check.
    vtkGarbageCollector::Collect(this);
  }
}

vtkObjectBaseToGarbageCollectorFriendship只是vtkGarbageCollector的warp类:

class vtkObjectBaseToGarbageCollectorFriendship {
public:
  static int GiveReference(vtkObjectBase* obj) { return vtkGarbageCollector::GiveReference(obj); }
  static int TakeReference(vtkObjectBase* obj) { return vtkGarbageCollector::TakeReference(obj); }
};

vtkWeakPointerBaseToObjectBaseFriendship是vtkWeakPointerBase类的warp类:

class vtkWeakPointerBaseToObjectBaseFriendship
{
public:
  static void AddWeakPointer(vtkObjectBase* r, vtkWeakPointerBase* p);
  static void RemoveWeakPointer(vtkObjectBase* r, vtkWeakPointerBase* p) noexcept;
  static void ReplaceWeakPointer(
    vtkObjectBase* r, vtkWeakPointerBase* bad, vtkWeakPointerBase* good) noexcept;
};

猜你喜欢

转载自blog.csdn.net/liushao1031177/article/details/124509717