带有对象的 Qt 容器
Posted
技术标签:
【中文标题】带有对象的 Qt 容器【英文标题】:Qt containers with object 【发布时间】:2015-02-25 19:00:32 【问题描述】:当使用 Qt 容器作为 Qlist、Qvector 等来保存某个类(比如具有许多数据成员和逻辑的复杂类)并调用 insert/append/push_back 时,添加到容器中的对象会被插入到容器中还是它将被复制(cctor)?
假设它被复制了,那么如果我动态分配它并传递一个指针,那么只有指针会被复制?如果我传递对象本身,那么我需要释放我之前分配的内存,因为对象被复制了?
我可以提供一些官方文档,所以我在这里问...
谢谢
【问题讨论】:
如果容器的模板类型是指针 - 那么对象将不会被复制。否则 - 将完成一个副本。 QObject children 已禁用复制 ctor,因此您不能将它们放入容器中。我建议你阅读官方文档和一些关于编程的书籍(容器,如 stl,和 RAII)。 【参考方案1】:在QObject
派生对象的情况下,您必须使用动态分配,只需将指针放入容器中,因为此类对象具有唯一标识,因此禁止复制。在这种情况下,只有指针被复制,它只是一个整数,它的复制对它指向的实际对象没有影响。对于动态分配的对象,您必须手动管理生命周期或使用 Qt 的父/子功能让对象被其父对象“收集”。
存储在各种容器中的值可以是任何可分配的数据类型。为了符合条件,一个类型必须提供一个默认构造函数,一个 复制构造函数和赋值运算符。 这涵盖了大多数数据 您可能想要存储在容器中的类型,包括基本的 类型如 int 和 double、指针类型和 Qt 数据类型如 QString、QDate 和 QTime,但不包括 QObject 或任何 QObject 子类(QWidget、QDialog、QTimer 等)。如果您尝试 实例化一个 QList,编译器会抱怨 QWidget 的复制构造函数和赋值运算符被禁用。
正如上面引用的文本所示,当将实际实例放入容器中时,将发生对象的复制。在这种情况下,您不必手动删除任何内容,因为副本的源通常是本地对象,通常是临时对象,编译器会处理这些。
“Placement new”是一个 C++ 功能,您可以使用它来指定对象在内存中的构造位置,但它带来了管理它的复杂性和一些限制。放置新池和内存池的优势很少超过复杂性的增加和灵活性的损失。
【讨论】:
以上是关于带有对象的 Qt 容器的主要内容,如果未能解决你的问题,请参考以下文章
Qt容器类的对象模型及应用(线性结构篇)(好多图,比较清楚)
Qt容器类的对象模型及应用(线性结构篇:对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true)