使用QObject而不是容器

时间:2013-10-07 00:29:40

标签: qt

在阅读了QObject有趣的亲子系统后,我想知道Qt开发人员使用它代替更传统的容器有多常见。假设存储器连续性不是必需的,似乎这提供了一些有趣的功能。

例如,您可以拥有QObject并为其提供不同类型的子项,然后根据其类型轻松找到所有子项,从而为QObject提供动态的异类容器式功能,而不是所需的同类型收集传统容器。

QObject自然地管理了孩子的记忆,这也很方便。

这是此功能的常用用途吗?

2 个答案:

答案 0 :(得分:5)

QObject::findChildren可能比将对象存储在像QList这样的普通容器中要慢得多,因为:

  1. 每次迭代所有孩子。它甚至可以递归搜索(但可以禁用)。
  2. 执行运行时类型检查。
  3. 每次都构造新的QList。这可能是缓慢而昂贵的,因此结果中有许多对象。
  4. 如果您只使用QList<Type*> my_objects,则无需上述所有内容。在这种情况下:

    1. 您可以为收藏品命名。 QList<QPushButton*> panic_buttonsfindChildren<QPushButton*>()更清晰。
    2. 您可以拥有多个相同类型的对象集合。
    3. 如果您想制作异类容器,可以使用QHash<any_type_identifier, QObject*>。它会更快。

      也许,findChildren方法有时可能更简单。但是如果你有很多对象或复杂的类,你最好使用普通的容器。您仍然可以使用QObject的内存管理而没有任何问题。

答案 1 :(得分:1)

正如@PavelStrakhov所述,使用QObject :: findChildren可能会更慢。但是,我使用的一种方法是将存储对象组合在QList中以及具有QObject父层次结构。它基于这样的事情: -

class BaseObject : public QObject
{
    Q_OBJECT

    public:

        static BaseObject* FindObject(unsigned int id); // find object by id

    private:
        unsigned int m_id;

        static unsigned int s_nextId; // next id for a new BaseObject
        static QList<QBaseObject*> s_objectsList; // list of all BaseObject-type instances
};

现在所有对象都继承BaseObject而不是QObject。创建新类时,BaseObject的构造函数将设置项的id,增加s_nextId,最后,将对象添加到s_objectsList。现在,查找对象很简单,只需搜索静态对象列表即可。

这可能不适合您正在开发的应用程序的设计,但它确实帮助了我,特别是在使用QGraphicsView / QGraphicsScene系统时。在这种情况下,BaseObject派生自QGraphicsObject。

当然,如果你使用了很多标准小部件,你就不太可能想要为它们创建新的类,但它是一个适合某些设计的选项。