VTK source code reading --vtkWeakPointerBase class

vtkWeakPointerBase class

        The vtkWeakPointerBase class holds a pointer to vtkObjectBase or a vtkObjectBase-derived class, but it never affects the reference count of vtkObjectBase . However, when the referenced vtkObjectBase is destroyed, the pointer is initialized to nullptr, thus avoiding dangling references.

        When using the vtkWeakPointerBase class object, it will modify the WeakPointers in the vtkObjectBase pointed to by the object

 vtkWeakPointerBase class declaration

        The header file declaration of the vtkWeakPointerBase class is as follows:

class VTKCOMMONCORE_EXPORT vtkWeakPointerBase
{
public:
  // 构造函数,将成员变量Object设置为空指针
  vtkWeakPointerBase() noexcept : Object(nullptr) {}
  // 构造函数,将成员变量Object设置为传入的指针
  vtkWeakPointerBase(vtkObjectBase* r);
  // 拷贝构造函数,将右值的data传入
  vtkWeakPointerBase(const vtkWeakPointerBase& r);
  // Move语义,将右值的Object指针转移到新vtkWeakPointerBase对象
  vtkWeakPointerBase(vtkWeakPointerBase&& r) noexcept;
  // 析构函数
  ~vtkWeakPointerBase();

  //@{
  // 重载赋值运算符,使用新的引用覆盖旧的引用
  vtkWeakPointerBase& operator=(vtkObjectBase* r);
  vtkWeakPointerBase& operator=(const vtkWeakPointerBase& r);
  vtkWeakPointerBase& operator=(vtkWeakPointerBase&& r) noexcept;
  //@}

  // 获取对象包含的原指针
  vtkObjectBase* GetPointer() const
  {
	// 以内联函数方式实现,所以智能指针比较可以完全内联;
    return this->Object;
  }

private:
  friend class vtkObjectBaseToWeakPointerBaseFriendship;

protected:
  // Initialize weak pointer to given object.
  class NoReference
  {
  };
  vtkWeakPointerBase(vtkObjectBase* r, const NoReference&);

  // 指向原对象的指针
  vtkObjectBase* Object;
};

      Here, vtkObjectBaseToWeakPointerBaseFriendship is set as the friend class of vtkWeakPointerBase class, because vtkObjectBaseToWeakPointerBaseFriendship will directly operate its member variable Object; it will be used in the vtkObjectBase class;

        In the vtkObjectBase.cxx file, the vtkObjectBaseToWeakPointerBaseFriendship class is defined:

class vtkObjectBaseToWeakPointerBaseFriendship
{
public:
  static void ClearPointer(vtkWeakPointerBase* p) { p->Object = nullptr; }
};

Six comparison operators are overloaded       using the macro VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR :

#define VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(op)                                                  \
  inline bool operator op(const vtkWeakPointerBase& l, const vtkWeakPointerBase& r)                \
  {                                                                                                \
    return (static_cast<void*>(l.GetPointer()) op static_cast<void*>(r.GetPointer()));             \
  }                                                                                                \
  inline bool operator op(vtkObjectBase* l, const vtkWeakPointerBase& r)                           \
  {                                                                                                \
    return (static_cast<void*>(l) op static_cast<void*>(r.GetPointer()));                          \
  }                                                                                                \
  inline bool operator op(const vtkWeakPointerBase& l, vtkObjectBase* r)                           \
  {                                                                                                \
    return (static_cast<void*>(l.GetPointer()) op static_cast<void*>(r));                          \
  }
/**
 * Compare smart pointer values.
 */
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(==)
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(!=)
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(<)
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(<=)
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(>)
VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR(>=)

#undef VTK_WEAK_POINTER_BASE_DEFINE_OPERATOR

 Implementation of the vtkWeakPointerBase class

        The constructor points the member variable Object to r;
        use the AddWeakPointer method of vtkWeakPointerBaseToObjectBaseFriendship to add this record to the WeakPointers in r;

vtkWeakPointerBase::vtkWeakPointerBase(vtkObjectBase* r)
  : Object(r)
{
  vtkWeakPointerBaseToObjectBaseFriendship::AddWeakPointer(r, this);
}
vtkWeakPointerBase::vtkWeakPointerBase(const vtkWeakPointerBase& r)
  : Object(r.Object)
{
  vtkWeakPointerBaseToObjectBaseFriendship::AddWeakPointer(r.Object, this);
}

        To implement move semantics, set the rvalue Object to null, call the ReplaceWeakPointer method of vtkWeakPointerBaseToObjectBaseFriendship to replace the r record in WeakPointers in vtkObjectBase pointed to by Object with this information;

vtkWeakPointerBase::vtkWeakPointerBase(vtkWeakPointerBase&& r) noexcept : Object(r.Object)
{
  r.Object = nullptr;
  vtkWeakPointerBaseToObjectBaseFriendship::ReplaceWeakPointer(this->Object, &r, this);
}

        The implementation of the destructor first calls the RemoveWeakPointer method of vtkWeakPointerBaseToObjectBaseFriendship to delete the record corresponding to this from the WeakPointers of the Object; set the Object to empty;

vtkWeakPointerBase::~vtkWeakPointerBase()
{
  vtkWeakPointerBaseToObjectBaseFriendship::RemoveWeakPointer(this->Object, this);
  this->Object = nullptr;
}

         Implementation of overloaded assignment operator:

vtkWeakPointerBase& vtkWeakPointerBase::operator=(vtkObjectBase* r)
{
  // 当前Object指向的vtkObjectBase跟r不是同一个对象;
  if (this->Object != r) {
    // 1.将Object原本指向的vtkObjectBase内的WeakPointers中删除this信息;
    vtkWeakPointerBaseToObjectBaseFriendship::RemoveWeakPointer(this->Object, this);
	// 2.将Object指向新的vtkObjectBase;
    this->Object = r;
	// 3.在新的vtkObjectBase中的WeakPointers追加this信息;
    vtkWeakPointerBaseToObjectBaseFriendship::AddWeakPointer(this->Object, this);
  }
  // 返回当前对象的引用;
  return *this;
}

vtkWeakPointerBase& vtkWeakPointerBase::operator=(const vtkWeakPointerBase& r)
{
  // 当前对象地址与r对象的地址不同;
  if (this != &r) {
	// 当前对象内的Object指针和r内的Object指针不是相同的地址时;
    if (this->Object != r.Object) {
	  // 1.将Object原本指向的vtkObjectBase内的WeakPointers中删除this信息;
      vtkWeakPointerBaseToObjectBaseFriendship::RemoveWeakPointer(this->Object, this);
	  // 2.将Object指向新的vtkObjectBase;
      this->Object = r.Object;
	  // 3.在新的vtkObjectBase中的WeakPointers追加this信息;
      vtkWeakPointerBaseToObjectBaseFriendship::AddWeakPointer(this->Object, this);
    }
  }
  // 返回当前对象的引用;
  return *this;
}

vtkWeakPointerBase& vtkWeakPointerBase::operator=(vtkWeakPointerBase&& r) noexcept
{
  // 当前对象地址与右值r对象的地址不同;
  if (this != &r) {
  	// 当前对象内的Object指针和r内的Object指针不是相同的地址时;
    if (this->Object != r.Object) {
	  // 1.将Object原本指向的vtkObjectBase内的WeakPointers中删除this信息;
      vtkWeakPointerBaseToObjectBaseFriendship::RemoveWeakPointer(this->Object, this);

      // WTB std::exchange
	  // 2.将Object指向新的vtkObjectBase;
      this->Object = r.Object;
	  // 3.将r对象内的Object设置为空,因为已经将它转移到了当前对象的Object中;
      r.Object = nullptr;
	  // 4.在新的vtkObjectBase中的WeakPointers追加this信息;
      vtkWeakPointerBaseToObjectBaseFriendship::ReplaceWeakPointer(this->Object, &r, this);
    }
  }
  // 返回当前对象的引用;
  return *this;
}

 vtkWeakPointerBaseToObjectBaseFriendship类

        The vtkWeakPointerBaseToObjectBaseFriendship class is the underlying implementation of the vtkWeakPointerBase class; the declaration and definition are located in the "vtkWeakPointerBase.cxx" file;        

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

        Implementation of AddWeakPointer:

        Its function is to add a new element p to the WeakPointers list of r;

void vtkWeakPointerBaseToObjectBaseFriendship::AddWeakPointer(
  vtkObjectBase* r, vtkWeakPointerBase* p)
{
  if (r) {
    vtkWeakPointerBase** l = r->WeakPointers;
	// 如果r的列表为空,即l==nullptr,需要创建一个新的vtkWeakPointerBase指针数组;
    if (l == nullptr) {
      // 创建一个含有两个元素的vtkWeakPointerBase*数组;
      l = new vtkWeakPointerBase*[2];
      l[0] = p;
	  // 将末尾元素设置为nullptr,作为边界值;
      l[1] = nullptr;
      r->WeakPointers = l;
    }
    else {
	  // 根据l的末尾元素为nullptr,则可以遍历到l的末尾,获取l的长度n;
      size_t n = 0;
      while (l[n] != nullptr) {
        n++;
      }
	  // 
      // 如果n+1是2的幂,则将列表大小增加一倍;
      if ((n & (n + 1)) == 0) {
	    // 用局部变量t暂存l的旧指针,之后会用来释放旧指针指向的内存空间;
        vtkWeakPointerBase** t = l;
		// 重新分配给l一个个数为(n + 1) * 2的vtkWeakPointerBase指针数组;
        l = new vtkWeakPointerBase*[(n + 1) * 2];
		// 将l原来空间内元素拷贝到新的内存空间中,这里为什么不使用memcpy???
        for (size_t i = 0; i < n; i++) {
          l[i] = t[i];
        }
		// 释放原来内存空间;
        delete[] t;
		// 更新r的WeakPointers指向新的列表;
        r->WeakPointers = l;
      }
      // 将p放在末尾位置;
      l[n++] = p;
	  // 将l列表末尾设置为nullptr;
      l[n] = nullptr;
    }
  }
}

        Implementation of the RemoveWeakPointer method:

        Its function is to delete the p pointer from r's WeakPointers;

void vtkWeakPointerBaseToObjectBaseFriendship::RemoveWeakPointer(
  vtkObjectBase* r, vtkWeakPointerBase* p) noexcept
{
  // 如果r不为空时;
  if (r) {
    vtkWeakPointerBase** l = r->WeakPointers;
	// 如果r内的WeakPointers不为空时;
	// 删除p的方式是,定位到p的前一个位置,然后将p之后的元素向前平移一个位置;
    if (l != nullptr) {
      size_t i = 0;
	  // 定位p的下标i;
      while (l[i] != nullptr && l[i] != p) {
        i++;
      }
	  // 从i开始,将i+1元素向前平移;
      while (l[i] != nullptr) {
        l[i] = l[i + 1];
        i++;
      }
	  // 如果l第一个元素为nullptr,表示l列表内有0个元素;
	  // 则删除l;将r内的WeakPointers置为空;
      if (l[0] == nullptr) {
        delete[] l;
        r->WeakPointers = nullptr;
      }
    }
  }
}

        The implementation of ReplaceWeakPointer is as follows:

        Its function is: replace bad in r's WeakPointers list with good;

void vtkWeakPointerBaseToObjectBaseFriendship::ReplaceWeakPointer(
  vtkObjectBase* r, vtkWeakPointerBase* bad, vtkWeakPointerBase* good) noexcept
{
  // 当r不为空时;
  if (r) {
    vtkWeakPointerBase** l = r->WeakPointers;
	// 当r的WeakPointers列表不为空时;
    if (l != nullptr) {
	  // 遍历l中元素,找到bad,然后替换为good;
      for (; *l != nullptr; ++l) {
        if (*l == bad) {
          *l = good;
          break;
        }
      }
    }
  }
}

Guess you like

Origin blog.csdn.net/liushao1031177/article/details/124523982
Recommended