我是否必须在下面的示例中从堆中删除对象?如果是的话,怎么样?
#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();
}
感谢您的帮助。
答案 0 :(得分:12)
只需在堆栈上分配splitter
即可。然后tree
,list
和table
成为拥有所有权的splitter
的子女。删除splitter
后,系统会删除所有子项。
来自Widgets Tutorial - Child Widgets:
该按钮现在是窗口的子项,在窗口被销毁时将被删除。请注意,隐藏或关闭窗口不会自动销毁它。当示例退出时,它将被销毁。
答案 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