Я должен удалить это? [Qt] - PullRequest
6 голосов
/ 19 января 2010

Нужно ли удалять объекты из кучи в примере ниже? И если да, то как?

#include <QApplication>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QSplitter>

int main(int argc, char* argv[])
{
    QApplication app(argc,argv);
    QTreeView* tree = new QTreeView;
    QListView* list = new QListView;
    QTableView* table = new QTableView;
    QSplitter* splitter = new QSplitter;
    splitter->addWidget(tree);
    splitter->addWidget(list);
    splitter->addWidget(table);
    splitter->show();
//    delete splitter; WHEN TRYING TO DELETE I'M GETTING INFO THAT app  EXITED
//    delete table;    WITH CODE -1073741819
//    delete list;
//    delete tree;
    return app.exec();
}

Спасибо за любую помощь.

Ответы [ 3 ]

12 голосов
/ 19 января 2010

Просто выделите splitter в стеке. Затем tree, list и table становятся детьми splitter, который становится владельцем. Когда splitter удаляется, все дочерние элементы удаляются.

Из Учебник по виджетам - дочерние виджеты :

Кнопка теперь является дочерним элементом окна и будет удалена при разрушении окна. Обратите внимание, что скрытие или закрытие окна не уничтожает его автоматически. Он будет уничтожен при выходе из примера.

См. Также Деревья объектов и владение объектами .

1 голос
/ 15 августа 2012

Грегори Пакош указал правильное решение, но я хотел повторить пример кода и предложить вам взглянуть на область действия объекта C ++. Грег точен, но не уточнил, что размещение сплиттера в стеке означает, что как только он выходит из области видимости (приложение выходит), он будет удален.

Точнее, вы должны установить родителя QObject. Когда родительский объект становится владельцем другого объекта, он удаляет своих детей после вызова delete родительского объекта. В случае QSplitters addWidget добавляет к макету QWidget, и макет становится владельцем этих объектов.

#include <QApplication>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QSplitter>

int main(int argc, char* argv[])
{
    QApplication app(argc,argv);

    QTreeView* tree = new QTreeView;
    QListView* list = new QListView;
    QTableView* table = new QTableView;

    QSplitter splitter;

    splitter.addWidget(tree);
    splitter.addWidget(list);
    splitter.addWidget(table);
    splitter.show();

    return app.exec();
}

Таким образом, простое создание 'splitter' локальной переменной приведет к ее удалению, когда он выходит из области видимости. В свою очередь это дети тоже будут удалены.

0 голосов
/ 28 ноября 2016

Вместо того, чтобы управлять памятью вручную, вы можете позволить компилятору сделать это за вас. В этот момент вы можете спросить: зачем вообще использовать кучу? Вы должны хранить как можно более ценные вещи и позволить компилятору выполнять тяжелую работу.

Объекты будут уничтожены в порядке, обратном объявлению. Таким образом, сплиттер - неявный родительский объект - должен быть объявлен первым, чтобы он не пытался некорректно удалить своих потомков. В C ++ порядок объявлений имеет значение!

int main(int argc, char* argv[])
{
    QApplication app(argc,argv);
    QSplitter splitter;
    QTreeView tree;
    QListView list;
    QTableView table;
    splitter.addWidget(&tree);
    splitter.addWidget(&list);
    splitter.addWidget(&table);
    splitter.show();
    return app.exec();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...