Evgenii Legotckoi
22 січня 2017 р. 21:33

Qt/C++ - Урок 059. Чи потрібно видаляти об'єкт QStandardItem з пам'яті після виклику методу clear у моделі даних?

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

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up