C++ 返回使用父对象的对象';s数据,然后使其无效
我正在Qt应用程序中开发一个表的实现,但是在正确设计时遇到了一些问题 我有两个类,C++ 返回使用父对象的对象';s数据,然后使其无效,c++,api,qt,C++,Api,Qt,我正在Qt应用程序中开发一个表的实现,但是在正确设计时遇到了一些问题 我有两个类,Table和Cell Cell具有用于设置单元格属性(如边框和填充)的API,并使用int Cell::row()和int Cell::column()获取单元格的行和列。它是一个显式共享类,用于其数据。它还有一个isValid()API来查询单元格是否有效 表具有用于插入/删除行和列以及合并单元格区域的API。可以使用table::cellAt(int行,int列)从表中检索单元格。单元格行保留为QList。删除
Table
和Cell
Cell
具有用于设置单元格属性(如边框和填充)的API,并使用int Cell::row()
和int Cell::column()
获取单元格的行和列。它是一个显式共享类,用于其数据。它还有一个isValid()
API来查询单元格是否有效
表
具有用于插入/删除行和列以及合并单元格区域的API。可以使用table::cellAt(int行,int列)
从表中检索单元格。单元格行保留为QList
。删除行和列时,表会将删除的单元格标记为无效,从而对以前从删除的行/列返回的任何单元格调用Cell::isValid
,返回false
现在进入棘手的部分:由于如果尚未获得单元格的行数和列数,则计算这些行数和列数是一项昂贵的操作,因此Table::cellAt(int row,int column)
方法在返回它之前显式地在单元格上设置行/列,而单元格
将它们保持为简单的int
成员。这意味着当查询其行/列时,单元格
可以快速回复
但问题来了;这也意味着,如果在单元格所在的行/列之前删除/插入行或列,则Cell::row()
和Cell::column
的值将不正确
我不能像删除它们所属的实际行/列时那样,将受影响的单元格标记为无效。因为稍后可能会有人再次检索该行/列中带有cellAt(int,int)
的单元格。而且这个单元格不应该是无效的
这里有人对更好的设计有什么建议吗?你可以做一个懒散的更新。也就是说,如果表格自上次更新单元格位置以来发生了更改,则仅在调用单元格:行
或单元格:列
时更新单元格位置信息,而不是在每次表格更改时更新单元格位置信息。这需要您在表
和单元格
中保留版本戳或其他内容。每次更新表时,都会更新版本<代码>单元格::行
和单元格:列
将首先检查单元格
的版本是否早于表
,如果是,则重新计算位置
与总是重新计算位置或每次更改都重新计算相比,这些额外的工作是否值得,我不能说。我与一位朋友讨论了这个问题,因为它看起来太像一个编程珍珠练习。这就是我们得出的结论:
- 创建用于计算索引的新结构。它可能类似于
struct Index{int n;}代码>
- 将行和列索引存储在两个
QList
中。让我们称之为维度
。正如您稍后将看到的,使用指针是至关重要的
- 单元格不再存储其行和列值。它们分别指向两个
维度中的一个元素。当查询它们的行和列时,现在有一个额外的指针取消引用,这应该不会太昂贵
- 当表中添加或删除了行和列时,可以向相应的
维度添加项或从中删除项
,并更新以下项的n
值。存储指针是必要的,因为QList
复制其值
现在,您将只更新受影响的行或列,而不是对受表操作影响的每个单元格重新编号,该操作的成本为O(行x列),而受影响的行或列的成本为O(行+列)。缺点是增加了代码复杂性,当查询单元格的行或列时,会进行两次取消引用的访问。我开始认为,每次从表中插入/删除行/列时,保持单元格中的行/列信息更新是这个问题的唯一正确答案?而不是在单元格从Table::cellAt(int,int)
返回时设置它。但渴望听到更多有经验的人的建议!我想这是关于性能的。我说得对吗?非常感谢,这是一种方法。然而,就我的目的而言,cellAt(int,int)API的返回速度比插入/删除行/列的操作要快得多,所以我真的开始认为保持单元格上的行/列始终更新对我来说是正确的方法。嗯,有趣的方法。我得考虑一下。在这种情况下,QList
就足够了,或者我必须创建一个新的结构吗?是的,QList就足够了。为什么我要使用struct?我需要休息一下。