返回处理父对象数据并在以后使其失效的对象

Returning objects that work with parent object's data and later invalidate them

本文关键字:对象 失效 处理 数据 返回      更新时间:2023-10-16

我正在Qt应用程序中实现表,但在正确设计方面遇到了一些困难。

我有两个班,TableCell

Cell具有API,用于设置单元格属性,如边框和填充,并使用int Cell::row()int Cell::column()获取单元格的行和列。它是一个显式共享类,对其数据使用QEexplicitySharedDataPointer。它还有一个isValid() API来查询单元格是否有效。

Table具有用于插入/移除行和列以及合并单元格区域的API。可以使用CCD_ 9从表中检索CCD_。单元格的行被保持为CCD_ 10。删除行和列时,表会将删除的单元格标记为无效,从而使对已删除行/列中任何先前返回的单元格的Cell::isValid调用返回false。

现在进入棘手的部分:由于如果尚未获得单元格的行和列数,则计算它们是一项昂贵的操作,因此Table::cellAt(int row, int column)方法在返回之前在Cell上显式设置行/列,而Cell则将它们保留为简单的int成员。这意味着Cell在查询其行/列时可以快速回复。

但问题来了;这也意味着,如果在单元格所在的行/列之前移除/插入行或列,则Cell::row()Cell::column的值将不正确。

我不能像删除它们所属的实际行/列时那样将受影响的单元格标记为无效。因为稍后可能会有人再次检索该行/列中具有cellAt(int, int)的单元格。并且该单元格不应该是无效的。

有人对这里更好的设计有什么建议吗?

您可以进行延迟更新。也就是说,不是每次表更改时都更新单元格的位置信息,而是仅在调用Cell:rowCell:column时更新它(如果自上次更新单元格位置以来表发生了更改)。这将要求您在TableCell中保留版本戳或其他内容。每次更新表时,都要更改版本。Cell::rowCell:column将首先检查Cell的版本是否比Table的版本旧,如果是,则重新计算位置。

与总是重新计算位置或重新计算每一个变化相比,这些额外的工作是否值得,我不能说。

我和一个朋友讨论了这个问题,因为它看起来太像是一个编程珍珠练习了。这就是我们的想法:

  • 创建一个新的索引计数结构。它可能是类似struct Index { int n; };的东西
  • 将行和列索引存储在两个QList<Index*>中。让我们把这些称为Dimension。正如您稍后将看到的那样,使用指针是至关重要的
  • 单元格不再存储其行和列值。它们分别指向两个Dimension中的一个元素。当查询它们的行和列时,现在有一个额外的指针取消引用,这应该不会太昂贵
  • 当表中添加或删除了行和列时,可以向相应的Dimension添加项或从中删除项,并更新以下项的n值。存储指针是必要的,因为QList复制其值

现在,您将只更新受影响的行或列,而不是对受表操作影响的每个单元格重新编号,该操作的成本为O(x),该操作具有成本为O的成本(rows+columns。缺点是在查询单元格的行或列时增加了代码复杂性和两次取消引用的访问。