如何在循环中初始化 QList 中的对象

How to initialize Objects in a QList in a loop

本文关键字:QList 对象 初始化 循环      更新时间:2023-10-16

在我的类中,我有一个成员变量;

QProcess* p1;

在某个函数中,我初始化并将其用作:

process1 = new QProcess();

它工作正常。现在我的情况是,我有许多这样的过程要开始。一种选择是将它们全部声明为成员函数:

QProcess* p1;
QProcess* p2;
QProcess* p3;
...

然后在需要时初始化所有这些。然而,这是太多的冗余工作。所以我尝试创建一个列表并在这样的循环中初始化它:

QList<QProcess*> procList;
for(int i=0; i<len; i++){
procList[i] = new QProcess();
}

它编译正常,但随后崩溃。是不是缺少了什么,或者我在这里做错了什么?

我还尝试在此列表中添加所有成员变量,例如:

for(int i=0; i<len; i++){
switch(i){
case 0:
procList[i] = p1;
break;
}
}

但这也具有与上述相同的结果

编辑:

根据您的建议,我尝试了:

procList.append(new QProcess());

以及procList.append(p1);

但结果是一样的,它可以编译但在运行时崩溃

编辑:所以我发现这个问题完全无关。我使用此代码的类本身(我创建的自定义类)没有默认构造函数。正如我在没有默认构造函数的情况下学到的那样,如果您初始化指针,它就会以某种方式崩溃......奇怪。指定默认构造函数后,它现在可以正常工作。

您正在访问未分配的内存区域。您的列表为空,并且您访问了一个无效的元素。 根据文档:https://doc.qt.io/qt-5/qlist.html#operator-5b-5d

T &QList::operator[](int i) 将索引位置 i 处的项作为 可修改的引用。i必须是列表中的有效索引位置(即 0 <= i <size())。>

如果在当前正在共享的列表上调用此函数, 它将触发所有元素的副本。否则,此函数将运行 在恒定的时间内。如果您不想修改列表,则应使用 QList::at().

尝试使用appendpush_back,请参阅 https://doc.qt.io/qt-5/qlist.html#push_back

PS:不是QT专家,但如果可能的话,你可能想研究一个QList的std::unique_ptr来管理你的记忆。否则,您可能会忘记删除其指针存储在列表中的堆分配元素。

编辑:OP报告该建议不起作用。我自己写了一个小例子(忽略可能的泄漏)。以下示例在使用operator[]时崩溃,但在调试模式下使用append(我在 Windows 中使用了 QT creator,在 MinGW 64 位中使用了 Qt 5.13.0)。OP 遇到的可能是工具链的某些问题,也可能是在append之前触发的一些未定义的行为。我建议OP尝试将我的代码复制/粘贴到一个干净的项目中并运行它。

#include <QList>
#include <QProcess>
int main()
{
QList<QProcess*> list;
for(int i = 0; i < 10; ++i){
QProcess * p = new QProcess();
//Decomment and crash
//list[i] = p;
//does not crash
list.append(p);
}
//Here you should cleanup
}