Працюючи з таблицями, та й загалом із різними даними у 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