题
我的一个项目,我有一个树QObject衍生的对象,其利用QObject的父子的功能,建树。
这是非常有用的,因为我使用的信号,并插槽,用夸脱的人看守的指针和预期父母的对象删除的孩子,当他们被删除。
到目前为止一切顺利。不幸的是我现在的项目需要我管理/改变了的儿童。QObject没有提供任何方式改变了其儿童(例外:QWidget的提高()功能-但这是没有用处的,在这种情况下)。 所以现在我在寻找一个战略制订的儿童。 我有一些想法,但是我不确定自己的优点&缺点:
选项A: 定义的排索引的成员变量
使用 int m_orderIndex
成员可变为一种关键,并提供一个 sortedChildren()
方法其返回的列表QObjects按这个键。
- 实现容易纳入现有的对象结构。
- 有问题时
QObject::children()
方法是重写-会导致问题在循环项目的顺序被改变了,也是更昂贵的不是默认的实现。 - 应该回落到QObject对象了如果所有的钥匙都是平等的,或者0/默认。
选项B: 多余的列表中的儿童
维持冗余的列表中的儿童 QList
, 和增加儿童的时候他们是创造和摧毁。
- 需要昂贵的跟踪的加入/删除的对象。这基本上会导致第二个孩子/父跟踪和多的信号/隙。QObject做所有这种国内已有的,所以它可能不是一个好主意再次这样做。也感觉像一个很大的膨胀是加入一个简单的事情,像改变了的儿童。
- 好的灵活性,因为一个QList的儿童可以修改作必要的。
- 允许儿童在QList更多的时间,或不在所有的(即使它可能还是个孩子的QObject)
选择C:...?
任何意见或反馈,特别是从人已经解决了这个在自己的项目,表示高度赞赏。新年快乐!
解决方案
我花了很多时间,通过所有这些选项在过去的几天,并讨论了它们与其他一些程序员。我们决定去 选项一.
每个对象我们的管理是一个孩子的父母对象。由于脱不提供任何手段重新排序,这些对象,我们决定增加一个 int m_orderIndex
酒店的每个目的,其defaults to0.
每个对象有一个访问功能 sortedChildren()
其中返回 QObjectList
的儿童。我们做什么,在这一职能是:
- 使用正常的
QObject::chilren()
功能,以获得一个名单的所有可用的儿童的对象。 dynamic_cast
所有对象我们的"基类",其提供的m_orderIndex
财产。- 如果对象是浇注,将它添加到一个临时的对象名单。
- 使用
qSort
一个自定义LessThan
能找出如果时,qsort需要改变的顺序两个对象。 - 返回临时目清单。
我们这样做,原因如下:
- 现有的码(尤其是脱自己的代码)可以继续使用
children()
而不必担心副作用。 - 我们可以使用正常的
children()
功能的地方,那里的订单并不重要,不具有任意的性能损失。 - 在地方,我们需要的命令列表中的儿童,我们只需更换
children()
通过sortedChildren()
并获得所需的效果。
一个好东西关于这种方法是,即便儿童不会改变如果所有的排序的指数设定为零。
对不起,回答我自己的问题,希望,启发人们同样的问题。;)
其他提示
什么喜欢的东西...
- QList listChildren=(QList)儿童();
- 排序listChildren
- foreach listChildren setParent(TempParent)
- foreach listChildren setParent(OriginalParent)
一个讨厌黑: QObject::儿童() 返回的一个参考,到常数。你可以抛弃的常量性以及因此而操纵的内部清单。
这是非常邪恶但是,并具有的风险无效的迭代其QObject保持内部。
我没有一个单独的选项C,但比备选案文A和B,你说话-4的字节(32位针32-bit integer)在任何一种情况,所以我会去选择B,因为你可以保留该名单进行排序。
为了避免的额外复杂性跟踪的儿童,可以作弊,并保持你的列表类和整理,但将其与sortedChildren方法的筛选出的所有非儿童。复杂性,明智的,任何事物这结束了周围O(nlogm)(n=儿童,m=列条目的,假定米>=n,即孩子们总是加入),除非你有一个大的转变上的儿童。让我们叫这个选项C。
快速排序,在你的建议选择一个,给你O(n2)(厕所),但也需要你检索指针、跟踪他们,检索整数等。合并的方法只需要一个列表中的指针(任何被O(n))。
我有同样的问题,我解决它通过选择B跟踪并不难,只要创建一种"无效addChild(类型*ptr);"和另外一个删除childitem.
你不遭受邪恶的冗余,如果你exclusivly存储范围内的儿童的私人/公共"子级列表"中(QList)的各项目和下降的QObject基础。它实际上是相当容易实现自动儿童免费免费的(虽然需要额外的父母指针)。