我需要删除它吗?[Qt]

6

在下面的示例中,我是否需要从堆中删除对象?如果是,怎么做?

#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
只需在堆栈上分配splitter。然后,treelisttable成为splitter的子项,并由其拥有。当删除splitter时,所有子项都将被删除。
摘自小部件教程 - 子小部件

按钮现在是窗口的子项,在窗口被销毁时将被删除。请注意,隐藏或关闭窗口不会自动销毁它。它将在示例退出时被销毁。

另请参见对象树和对象所有权

但是我必须删除分割器对象吗?还是应该将它放在堆栈上? - There is nothing we can do
啊,好的,我会把“splitter”放在堆栈上。 - Gregory Pakosz
是的,要么删除它,要么将其放在堆栈上。 - mtvec

1

Gregory Pakosz指出了正确的解决方案,但我想通过代码示例重申,并建议您研究C++对象作用域。Greg是准确的,但没有澄清将分裂器放在堆栈上意味着一旦超出范围(应用程序退出),它将被删除。

更准确地说,您应该设置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

与其手动管理内存,不如让编译器为您处理。此时您可能会问:为什么还要使用堆呢?应该尽可能地按值保存事物,并让编译器来完成艰苦的工作。

对象将按声明的相反顺序销毁。因此,分裂器 - 隐式父项 - 必须首先声明,以便它不会尝试错误地删除其子项。在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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接