【1】qDeleteAll应用示例

qDeleteAll源码如下:

template <typename ForwardIterator>
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
{
while (begin != end)
{
delete *begin;
++begin;
}
}

template <typename Container>
inline void qDeleteAll(const Container &c)
{
qDeleteAll(c.begin(), c.end());
}

示例代码如下:

#include <QMap>
#include <QString>
#include <QWidget>
#include <QDebug>
#include <QApplication>

class PersonInfo
{
public:
PersonInfo(int id = -1, QString name = QString(), QWidget* pWidget = NULL)
: m_nId(id)
, m_name(name)
, m_pWidget(pWidget)
{}

~PersonInfo()
{
m_nId = -1;
m_name = QString();
if (m_pWidget != NULL)
{
qDebug() << "delete personInfo :: " << this;
delete m_pWidget;
m_pWidget = NULL;
}
}
private:
int m_nId;
QString m_name;
QWidget* m_pWidget;
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QMap<int, PersonInfo *> map;
for (int i = 0; i < 10; ++i)
{
PersonInfo *pTemp = new PersonInfo(i + 1, QString("hello World!"), (new QWidget()));
qDebug() << "construct personInf :: " << pTemp;
map.insert(i, pTemp);
}

qDeleteAll(map); // 1.释放内存
qDebug() << "after qDeleteAll size :: " << map.size() << endl;
map.clear(); // 2.必须清空
qDeleteAll(map); // 3.再次释放内存

return a.exec();
}

打印结果如下:

construct personInf ::  0x3bdc20
construct personInf :: 0x3c0308
construct personInf :: 0x3bfe08
construct personInf :: 0x3c0a88
construct personInf :: 0x3c1248
construct personInf :: 0x3c1738
construct personInf :: 0x3c1bb8
construct personInf :: 0x3c2420
construct personInf :: 0x3c26d0
construct personInf :: 0x3c2c68
delete personInfo :: 0x3bdc20
delete personInfo :: 0x3c0308
delete personInfo :: 0x3bfe08
delete personInfo :: 0x3c0a88
delete personInfo :: 0x3c1248
delete personInfo :: 0x3c1738
delete personInfo :: 0x3c1bb8
delete personInfo :: 0x3c2420
delete personInfo :: 0x3c26d0
delete personInfo :: 0x3c2c68
after qDeleteAll size :: 10

尤其注意打印结果。

可以尝试把2.清空容器行注释掉,然后再运行程序,查看运行结果。

【2】总结

qDeleteAll只负责释放容器元素内存,但没有对容器的置空操作。若无意间二次再执行qDeleteAll过程,程序必会崩溃。

为了避免可恶的崩溃,切记qDeleteAll之后必须清空容器。