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 はそのメンバー変数 Object を直接操作し、vtkObjectBase クラスで使用されるため、vtkObjectBaseToWeakPointerBaseFriendship は vtkWeakPointerBase クラスのフレンド クラスとして設定されます。

        vtkObjectBase.cxx ファイルでは、vtkObjectBaseToWeakPointerBaseFriendship クラスが定義されています。

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

6 つの比較演算子は、      マクロ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 に追加します。

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

        移動セマンティクスを実装するには、右辺値オブジェクトを null に設定し、vtkWeakPointerBaseToObjectBaseFriendship の ReplaceWeakPointer メソッドを呼び出して、Object が指す vtkObjectBase の WeakPointers の r レコードをこの情報で置き換えます。

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

        デストラクターの実装は、最初に vtkWeakPointerBaseToObjectBaseFriendship の RemoveWeakPointer メソッドを呼び出して、これに対応するレコードをオブジェクトの WeakPointers から削除し、オブジェクトを空に設定します。

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 の実装:

        その機能は、新しい要素 p を r の WeakPointers リストに追加することです。

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