【发布时间】:2018-11-30 16:20:43
【问题描述】:
我对 Qt 和 C++ 很陌生(我一生都在研究 C# 和 Java),而且我几乎一直在阅读我不应该再使用原始指针的所有内容(除了构造函数和析构函数中的指针,遵循 RAII 原则)。
我没问题,但有一个问题,如果没有指针,我无法轻松解决。
我会尽力解释我的问题。
我正在创建一个由我创建的自定义类 (MyClass) 的 QList,它将充当我的应用程序的模型:
QList<MyClass> modelList;
此 QList 由工作线程根据来自网络的信息进行更新(添加、删除或更新项目)。
到目前为止一切顺利。
现在我有另一个线程(GUI 线程),它有一个可绘制项目的 QList(MyDrawableItem)。这些项目中的每一个都有一个成员,该成员必须指向第一个 QList (modelList) 中的一个项目,如下所示:
QList<MyDrawableItem> listToDraw;
地点:
class MyDrawableItem
{
private:
MyObject *pointedObject;
//List of many other members related to drawing
}
因为每次 GUI 线程中的计时器到期时,我都必须根据指向的对象更新绘图相关成员。必须注意,按照文档中的说明,保留指向 QList 成员的指针是安全的:
注意:QLinkedList 中的迭代器和堆分配中的引用 只要引用的项目仍在 容器。这不适用于迭代器和对 a 的引用 QVector 和非堆分配 QLists。
在内部,如果 sizeof(T)
如果不使用指针,这怎么可能可行?或者更好的是,做这种工作的最佳方式应该是什么?
我找到了三种可能的解决方案:
不要将pointedObject 保留为MyDrawableItem 的成员,而是将指向对象的索引保留在modelList 中。然后在更新中查看 QList 内部。但是如果列表中的项目被删除了怎么办?我可以发出信号,但如果更新发生在调用插槽之前?
不要将任何东西保留为成员,并将两个信号连接到 MyDrawableItem。一个信号是
updateDrawing(const MyObject&),它更新与绘图相关的成员,另一个信号是removeDrawing(),它只是删除对象。这样我就不必担心线程之间的同步,因为 MyDrawableItem 对象永远不会查看 QList 的内容。在这种情况下,我可能会经常使用大量信号更新项目,而我只想偶尔更新一次 GUI(500 毫秒的计时器)。只需使用指针。
发展并使用 QSharedPointers,但我从未使用过这些,我不知道这是否是最佳选择。
我认为这些解决方案都不是完美的,所以我在这里寻求您的帮助。
Qt 中的标准视图(tableview、listview、ecc.)如何处理这个问题?
我应该如何处理?
请帮帮我,我从昨天开始就在想这个,我不想弄得一团糟。
非常感谢!
【问题讨论】:
-
一般来说,原始指针没有问题。你应该避免的是原始的 owning 指针。指向容器中元素的指针的问题是,一些容器在添加新元素时必须重新分配它们的内存,呈现指向元素的指针无效(实际上我不知道
QList是否是这种情况) -
@user463035818
QList<T>是指向T的指针向量。当调整QList的大小时,只有向量被重新分配,而不是指向的Ts。然而对于小类型,QList被优化为直接将Ts 存储在向量中。这就是为什么引用的 Qt 文档在“堆分配和非堆分配 QList”之间有所不同。