Beim Arbeiten mit Tabellen, und zwar mit diversen Daten in C++, ist eine Kontrolle über das Löschen erforderlich, damit es nicht zu Speicherlecks kommt. Aber ist eine solche vollständige Kontrolle erforderlich, wenn QStandardItem -Objekte gelöscht werden, die in einem QStandardItemModel platziert sind, dessen clear -Methode aufgerufen wurde?
Eine solche Frage kann sich aus der Art und Weise ergeben, wie QStandardItem -Objekte normalerweise zu QStandardItemModel hinzugefügt werden, nämlich:
QList<QStandardItem *> items; items.append(new QStandardItem("Item 1")); items.append(new QStandardItem("Item 2")); items.append(new QStandardItem("Item 3")); model->appendRow(items);
Und so weiter in einer Schleife, um die erforderliche Anzahl von Zeilen auszufüllen. Gleichzeitig erscheinen Zeiger auf diese Objekte an keiner anderen Stelle im Code und werden nicht gelöscht. Es stellt sich also die Frage, was passiert, wenn die Methode clear aufgerufen wird.
Wenn ein QStandardItem -Objekt an ein QStandardItemModel übergeben wird, wird der Besitz dieser Objekte an das Modell übergeben. Und wenn die Methode clear aufgerufen wird, entfernt das Modell diese Objekte automatisch aus dem Speicher.
Der folgende Code demonstriert dies.
Hauptfenster.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
Hauptfenster.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(); }
Aussehen der Anwendung
In diesem Fall hat das Anwendungsfenster QTableView , das QStandardItemModel, enthält, und es gibt auch eine Schaltfläche QPushButton , durch deren Klick das Datenmodell gelöscht wird.
QDebug-Ausgabe
Und in der Ausgabe von qDebug() werden wir sehen, wie die Destruktoren von QStandardItem ausgelöst werden, wenn die Schaltfläche QPushButton. gedrückt wird.
Item created 0x16e3540 Item created 0x16ecdd0 Item created 0x16e4e80 Item destroyed 0x16e3540 Item destroyed 0x16ecdd0 Item destroyed 0x16e4e80