返回使用父对象数据的对象,然后使它们无效

时间:2011-06-10 20:17:00

标签: c++ api qt

我正在研究Qt应用程序中的表的实现,但在设计正确时遇到一些麻烦。

我有两个课程,TableCell

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

Table具有用于插入/删除行和列以及合并单元格区域的API。可以使用Cell从表中检索Table::cellAt(int row, int column)。细胞行保持为QList<QList<Cell>>。删除行和列时,表中将删除的单元格标记为无效,这使得对已删除的行/列中任何先前返回的单元格的Cell::isValid的调用返回false。

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

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

我无法将受影响的单元格标记为无效,就像删除它们所属的实际行/列时一样。由于以后有人可能会再次在该行/列中检索Cell::column的单元格。那个细胞不应该是无效的。

有没有人对这里更好的设计有一些建议?

2 个答案:

答案 0 :(得分:2)

你可以做一个懒惰的更新。也就是说,不是每次表更改时更新单元格的位置信息,而是在自上次更新单元格位置后表格已更改时,仅在调用Cell:rowCell:column时更新它。这需要您在TableCell中保留版本标记或其他内容。每次表格更新时,都会碰撞版本。 Cell::rowCell:column会首先检查Cell的版本是否早于Table,如果是,请重新计算该位置。

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

答案 1 :(得分:0)

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

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

不是重新编号受表操作影响的每个Cell,而是一个成本为O( x )的操作,您现在只更新受影响的行或列,其成本为O( + )。当查询Cell的行或列时,缺点是增加了代码复杂性和两个解除引用的访问。