VTK源码阅读--vtkWeakPointerBase类

vtkWeakPointerBase类

        vtkWeakPointerBase类中持有一个指向vtkObjectBase或者vtkObjectBase派生类的指针,但它从不影响vtkObjectBase的引用计数。但是,当引用的vtkObjectBase被销毁时,指针被初始化为 nullptr,从而避免了悬空引用。

        使用vtkWeakPointerBase类对象时,会修改对象指向的vtkObjectBase内的WeakPointers

 vtkWeakPointerBase类声明

        vtkWeakPointerBase类的头文件声明如下:

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

      这里设置vtkObjectBaseToWeakPointerBaseFriendship为vtkWeakPointerBase类的友元类,是因为vtkObjectBaseToWeakPointerBaseFriendship会直接操作它的成员变量Object;会在vtkObjectBase类中使用到;

        在vtkObjectBase.cxx文件中,定义了vtkObjectBaseToWeakPointerBaseFriendship类:

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

      使用宏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

 vtkWeakPointerBase类的实现

        构造函数将成员变量Object指向r;
        使用vtkWeakPointerBaseToObjectBaseFriendship的AddWeakPointer方法将r内的WeakPointers增加this的记录;

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

        移动语义的实现,将右值的Object设置为空,调用vtkWeakPointerBaseToObjectBaseFriendship的ReplaceWeakPointer方法将Object指向的vtkObjectBase内的WeakPointers中的r记录更换为this信息;

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

        析构函数的实现,首先调用vtkWeakPointerBaseToObjectBaseFriendship的RemoveWeakPointer方法,从Object的WeakPointers中删除this对应的记录;将Object置为空;

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

         重载赋值运算符的实现:

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类

        vtkWeakPointerBaseToObjectBaseFriendship类是vtkWeakPointerBase类的底层实现;声明和定义位于“vtkWeakPointerBase.cxx”文件内;        

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

        AddWeakPointer的实现:

        其功能为在r的WeakPointers列表中,追加新的元素p;

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

        RemoveWeakPointer方法的实现:

        其功能为从r的WeakPointers中删除p指针;

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

        ReplaceWeakPointer的实现如下:

        其功能为:将r的WeakPointers列表中的bad替换为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;
        }
      }
    }
  }
}

猜你喜欢

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