При работе с таблицами, да и вообще с различными данными в C++ требуется контроль над удалением, чтобы не было утечек памяти. Но требуется ли такой тотальный контроль при удалении объектов QStandardItem помещённых в QStandardItemModel , у которой вызвали метод clear ?
Такой вопрос может возникнуть исходя из того, каким образом обычно добавляются объекты QStandardItem в QStandardItemModel, а именно:
QList<QStandardItem *> items; items.append(new QStandardItem("Item 1")); items.append(new QStandardItem("Item 2")); items.append(new QStandardItem("Item 3")); model->appendRow(items);
И так далее в цикле для заполнения необходимого числа строк. При этом указатели на данные объекты нигде в коде больше не фигурируют и не удаляются. Поэтому и возникает вопрос о том, что происходит, если вызвать метод clear .
Когда объект QStandardItem передаётся в QStandardItemModel , то права собственности на данные объекты передаются в модель. И при вызове метода clear модель автоматически удаляет эти объекты из памяти.
Ниже следующий код это демонстрирует.
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStandardItemModel> #include <QStandardItem> #include <QDebug> class DestroyedItem: public QStandardItem { public: DestroyedItem(const QString & text): QStandardItem(text) { qDebug() << "Item created" << this; } ~DestroyedItem() { qDebug() << "Item destroyed" << this; } }; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; QStandardItemModel *model; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QSharedPointer> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); model = new QStandardItemModel(ui->tableView); // Устанавливаем заголовки колонок таблицы model->setHorizontalHeaderLabels(QStringList() << "Column 1" << "Column 2" << "Column 3"); QList<QStandardItem *> items; items.append(new DestroyedItem("Item 1")); items.append(new DestroyedItem("Item 2")); items.append(new DestroyedItem("Item 3")); model->appendRow(items); // Устанавливаем модель в объект QTableView ui->tableView->setModel(model); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { model->clear(); }
Внешний вид приложения
В данном случае в окне приложения имеется QTableView , в котором находится QStandardItemModel, а также присутствует кнопка QPushButton , по нажатию на которую модель данных очищается.
Вывод QDebug
А в выводе qDebug() мы увидим, как срабатывают деструкторы QStandardItem при нажатии кнопки QPushButton.
Item created 0x16e3540 Item created 0x16ecdd0 Item created 0x16e4e80 Item destroyed 0x16e3540 Item destroyed 0x16ecdd0 Item destroyed 0x16e4e80