【问题标题】:Deallocation of items in QStandardItemModelQStandardItemModel 中项目的重新分配
【发布时间】:2018-08-13 12:49:17
【问题描述】:

当分配在堆栈上的QStandardItemModel 被销毁时,模型中的指针指向的对象会发生什么情况(例如,item/item2 指针,如下例所示):

QStandardItem* item = new QStandardItem("test");
QStandardItem* item2 = new QStandardItem("test2");

QList<QStandardItem*> list;
list.append(item);
list.append(item2);

QStandardItemModel model;
model.addRow(list);

在这种情况下,如果我理解正确,模型中的行由 N 个值组成,该行中的每个值表示为 QStandardItem。这意味着上面的“列表”对象是一行,有两个值(列)。

这比使用model.setData()model.setRowCount() 和手动跟踪坐标是好还是坏?

如果需要完整的上下文,则为 here。想法是手动循环 QSqlQuery 结果并以块的形式获取行。相关方法称为loadChunk

如果模型是堆栈分配的,我是否需要以某种方式管理通过 addRow() 加载到模型的项目的解除分配

TLDR;如何确保模型在分配堆栈时不会泄漏内存,但包含大量指向堆上对象的指针?

【问题讨论】:

  • 使用C++智能指针换行QStandardItem-:)

标签: c++ memory-management qt5 qlist qstandarditem


【解决方案1】:

注意:是QStandardItemModel::appendRow,而不是QStandardItemModel::addRow

现在进入主题:

您无需担心手动销毁 QStandardItem 对象。当它们所属的模型被销毁时,它们也将被销毁。

为了演示从 QStandardItem 继承并在析构函数中放入调试消息,如下所示:

MyItem.h

#ifndef MYITEM_H
#define MYITEM_H

#include <QStandardItem>

class MyItem : public QStandardItem
{
public:
    explicit MyItem(const QString &text);
    ~MyItem();
};

#endif // MYITEM_H

MyItem.cpp

#include "MyItem.h"

MyItem::MyItem(const QString &text) :
    QStandardItem(text)
{

}

MyItem::~MyItem()
{
    qDebug("Gone");
}

MainWindow.cpp

#include "MainWindow.h"
#include "MyItem.h"
#include <QStandardItemModel>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QStandardItemModel model;
    auto *item = new MyItem("test");

    model.appendRow(item);
}

您也可以尝试:

auto *model = new QStandardItemModel(this);
model->appendRow(item);
model->deleteLater();

在任何一种情况下,应用程序都应在运行后立即输出“Gone”。

顺便说一句,使用model-&gt;removeRow(model-&gt;rowCount() - 1); 代替model-&gt;deleteLater(); 时的结果是一样的。

至于代码中的QList&lt;QStandardItem*&gt; list;list 是一个局部变量。它用作将项目传递给模型的容器。之后它就没有必要了,并且在超出范围时被销毁。然而,这些项目将继续存在,直到从模型中删除或模型被销毁。

【讨论】:

  • 即使指针被包裹在列表中并且列表被添加到模型中?出现这个问题是因为我在网上发现使用 QList 时,人们必须使用 qDeleteAll() 释放对象。
  • 模型存在时?还是循环迭代?
  • 谢谢,那是我不清楚的部分。所以 list 被用作载体,一旦被 appendRow 方法使用,它就会被丢弃,因为 appendRow 以某种方式获取指针并取得它们的所有权。从那时起,指针归模型所有,因此删除子项的工作方式与您演示的一样(并在文档中提到)。
  • @mispp 没错!
  • @mispp,请允许我说一下。 list 不会被 appendRow 丢弃。它在超出范围时被销毁。模型拥有的不是指针,而是对象。如果您决定保留一个指针并且它指向的对象被销毁,则该指针将变得悬空。
猜你喜欢
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多