参见英文答案 >
Creating and deallocating a Qt widget object2
我听说Qt中的对象会自动删除他们的孩子,我想知道在这些情况下会发生什么.
我听说Qt中的对象会自动删除他们的孩子,我想知道在这些情况下会发生什么.
#include <QApplication> #include <QLabel> #include <QHBoxLayout> #include <QWidget> int main(int argc,char **argv) { QApplication app(argc,argv); /* QLabel label("label"); // Program will crash. Destruct order is 1. widget,2. layout,3. label QHBoxLayout layout; // But layout will be deleted twice QWidget widget; */ QWidget widget; // Program doesn't seem to crash but is it safe ? Does Qt use QHBoxLayout layout; // delete to operate on already destructed children ? QLabel label("label"); layout.addWidget(&label); // layout is label's parent widget.setLayout(&layout); // widget is layout's parent widget.show(); return app.exec(); }
这是否允许在Qt? Qt在摧毁孩子时做什么?
BTW,我考虑使用诸如shared_ptr之类的智能指针.但是我认为Qt也会删除已经被智能指针破坏的对象.
我知道你想使用新的为对象分配动态内存.但是我不觉得安心,请告诉我有没有任何情况(例如例外)会导致内存泄漏,依靠Qt的对象树来处理动态内存?
如果我使用对象而不是指针来动态分配对象,只要拥有所有权,我就必须考虑到对象的销毁顺序,这是乏味的.
我不知道在Qt中使用动态内存是否是最佳做法.
你有什么建议还是更好的解决方案?
解决方法
Composite Design Pattern的QObject实现已经通过许多版本的Qt进行了测试和测试.
该模式要求复合对象获取所有子节点,只要父节点完成,您就可以放心,当父节点被破坏时,孩子QObject将被销毁.
标准做法是在堆内存中创建子对象,并立即对其进行父对象.如果您不立即使用父类,则可以使用setParent()函数显式地使用父类,或者使用addWidget()或addLayout()将widget添加到父窗口小部件时,父项将自动完成.
QLayout对象是其他QLayout和QWidget的大小和布局管理器.他们没有自己管理的对象.父亲其实是QWidget,QLayout是孩子的孩子.
您可以选择在堆栈内存或堆内存中创建根父进程.
如果您对智能指针感到更舒适,则有两个专门用于QObjects的类:QPointer和QSharedPointer.每个都有其优缺点.
#include <QApplication> #include <QLabel> #include <QHBoxLayout> #include <QWidget> int main(int argc,argv); QWidget widget; // Root parent so can create as a auto-deleting object on the stack QHBoxLayout *layout = new QHBoxLayout(&widget); // Create on the heap and parent immediately QLabel *label = new QLabel("label",&widget); // Create on the heap and parent immediately layout->addWidget(label); // widget remains label's parent widget.setLayout(layout); // widget is changed to layout's parent if necessary,as well // as any widgets that layout manages widget.show(); return app.exec(); // layout and label are destroyed when widget is destroyed }