首先,第一件事:我知道从容器扩展是一种不好的做法,我也知道原因。另一方面,我正在“播放已经处理过的代码”,没有时间适当地重构它。

我有一个类,我们称它为VectorOfSomethings,它是从QVector<Something>扩展而来的。每个Something都有一个hashCode()方法,该方法可以唯一地标识它。

另一方面,还有许多其他类具有VectorOfSomethings类型的成员,并且还有许多operator == implemented作为m_Somethings == other.m_Somethings。这些运算符称为A LOT。

由于没有实际的方法来急切地计算哈希值,因此我不得不依靠VectorOfSomethings::hashCode()方法,该方法会遍历所有当前存储的Somethings,并根据其哈希值立即计算集合的哈希值。这是 super 昂贵的。

拦截对VectorOfSomethings的所有写操作的最有效方法是什么,因此每次在其中添加/删除某项内容时,都将重新计算和缓存哈希值,以便在需要时为operator ==准备就绪?

尝试重载原始QVector方法。非常优雅。在某些情况下不起作用(这远比不雅致)。

这是代码现在的外观示意图:

class VectorOfSomething : public QVector<Something>, public SomeOtherNonEssentials
{
  public:

    // Insert other methods here

    uint hashCode() const {
      uint result = 0;
      std::for_each(this->begin(), this->end(), [&result](Something value) {
        result = regenerateHash(result, value.hashCode());
      });

      return result;
    }

    bool operator==(const VectorOfSomething &other) const
    {
      return hashCode() == other.hashCode();
    }
}

最佳答案

不要从Qt容器继承(与STL容器一样,它们不旨在被继承,一个提示是它们没有虚拟析构函数)。

因此,使用composition并为内部 vector 提供所需的接口(interface),这也将解决您的问题,它将拦截所有修改:

//Optional make it generic
class VectorOfSomething : public SomeOtherNonEssentials
{
  public:
    // Insert other methods here
    // insert methods like insert/remove/add/push_back
    void push_back(const Something& something)
    {
      //do whatever with something
      m_internalVector.push_back(something);
    }
  private:
    QVector<Something> m_internalVector;
}

关于c++ - 如何拦截QVector上的写操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57259793/

10-11 16:27