我必须删除它吗? [Qt的]

时间:2010-01-19 09:48:32

标签: qt

我是否必须在下面的示例中从堆中删除对象?如果是的话,怎么样?

#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 个答案:

答案 0 :(得分:12)

只需在堆栈上分配splitter即可。然后treelisttable成为拥有所有权的splitter的子女。删除splitter后,系统会删除所有子项。

来自Widgets Tutorial - Child Widgets

  

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

另见Object Trees and Object Ownership

答案 1 :(得分: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'作为局部变量会导致它在超出范围时被删除。反过来,它的孩子也将被删除。

答案 2 :(得分:0)

您可以让编译器为您执行此操作,而不是手动管理内存。那时你可能会问:为什么要使用堆呢?你应该尽可能地保持价值,让编译器付出艰苦的努力。

对象将按声明的相反顺序销毁。因此,必须首先声明拆分器(隐式父级),以便它不会尝试错误地删除其子级。在C ++中,声明的顺序有意义!

items