当它们的容器被破坏时,如何删除这些动态分配的对象?

Posted

技术标签:

【中文标题】当它们的容器被破坏时,如何删除这些动态分配的对象?【英文标题】:How can I delete these dynamically allocated objects when their container is destructed? 【发布时间】:2018-12-17 21:46:01 【问题描述】:

我有一个指向 QStandardItems 的指针 QList,我将其附加到用于 QTableView 的 QStandardItemModel。我希望在 fileListView 被破坏时删除 QStandardItems 和 MODDataFile。实现这一目标的最佳方法是什么?

foreach (QString fileName, fileList)

    MODDataFile *file = new MODDataFile(dir.filePath(fileName)); 
    QList<QStandardItem*> row;

    QStandardItem *item = new QStandardItem();
    item->setData(QVariant::fromValue(file));
    row.append(item);

    row.append(new QStandardItem(file->mUserInfo["TestID"])); 
    row.append(new QStandardItem(fileName));
    row.append(new QStandardItem(file->mTimeAndLocation["Date"]));

    mFileModel.appendRow(row);


ui->fileListView->setModel(&mFileModel);

我尝试只使用 QStandardItem 对象而不是指针,但 QStandardItemModel::appendRow() 需要 QList&lt;QStandardItem*&gt;。 file 是一个指针,因为它们是大类,我想将它们传递给其他类。

【问题讨论】:

你能在这些中使用std::unique_ptr吗? “我想把它们传给其他班级”是什么意思?听起来你需要std::shared_ptr Qt 实际上会自动(通常)清理子 QObject,因此您不必担心 QStandardItem,但对于 MODDataFile,您必须遍历行并删除它们。我不认为 unique_ptr 会很好用,因为 Qvariant::fromvalue() 需要一个副本。但是 shared_ptr 会,或者因为你已经在使用 Qt,你可以使用 QSharedPointer。 @TonyJ 因此,如果我将 MODDataFile 封装在 QSharedPointer 中,它们将被自动删除而无需遍历列表,对吧? 什么是 mFileModel?如果它是 QStandardItemModel,您不必担心,因为它需要所有权。否则,这取决于您如何构建模型。数据通常应该属于模型,而不是 gui 元素。并且@TonyJ,QStandardItem 不继承自 QObject。 【参考方案1】:

您可以替换以下代码行:

MODDataFile *file = new MODDataFile(dir.filePath(fileName)); 
QList<QStandardItem*> row;

QStandardItem *item = new QStandardItem();
item->setData(QVariant::fromValue(file));
row.append( item );

row.append(new QStandardItem(file->mUserInfo["TestID"])); 
row.append(new QStandardItem(fileName));
row.append(new QStandardItem(file->mTimeAndLocation["Date"]));

mFileModel.appendRow(row);

与:

std::shared_ptr<MODDataFile> file = std::make_shared<MODDataFile>();
QList<std::shared_ptr<QStarndardItem>> row;

std::shared_ptr<QStandardItem> item = std::make_shared<QStandardItem>();
item->setData(QVariant::fromValue(file));
row.append( item );

row.append( std::shared_ptr<QStandardItem>( new QStandardItem( file->mUserInfo["TestID"])));
row.append( std::shared_ptr<QStandardItem>( new QStandardItem(filename));
row.append( std::shared_ptr<QStandardItem>( new QStandardItem(file->mTimeAndLocation["Data"])));

mFileModel.appendRow(row);

使用shared_ptrunique_ptr 将在您对它们调用释放或它们超出范围时清理您的内存。当它们超出范围时,它们的析构函数将为您清理所有内存和引用计数。这也取决于mFileModel 是什么,以及您如何设计模型。

【讨论】:

以上是关于当它们的容器被破坏时,如何删除这些动态分配的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测新对象何时被生成或从统一中删除以获得评分/分数?

动态内存

动态内存和智能指针

动态内存——动态内存与智能指针

Spritekit物理会破坏对象动画

动态内存&对象