4

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

例如,您可以拥有一个QObject并赋予它不同类型的子代,然后根据它们的类型轻松找到所有子代,从而为 QObject 提供动态的异质容器类功能,而不是传统容器所需的同质集合。

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

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

4

2 回答 2

5

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

  1. 它每次都遍历所有孩子。它甚至可以递归搜索(但这可以禁用)。
  2. 它执行运行时类型检查。
  3. 它每次都构造新的 QList。如果结果中有很多对象,这可能会很慢而且很昂贵。

如果您只是使用,以上所有这些都是不必要的QList<Type*> my_objects。同样在这种情况下:

  1. 您可以命名您的收藏。QList<QPushButton*> panic_buttons比 更清楚findChildren<QPushButton*>()
  2. 您可以拥有多个相同类型的对象集合。

如果要制作异构容器,可以使用QHash<any_type_identifier, QObject*>. 它会更快。

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

于 2013-10-07T01:27:14.183 回答
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 派生的。

当然,如果您使用大量标准小部件,则不太可能希望为它们创建新类,但它是适合某些设计的选项。

于 2013-10-07T08:11:26.107 回答