Qt如何删除对象?存储 QObjects 的最佳方式是什么? [英] How does Qt delete objects ? And what is the best way to store QObjects?

查看:64
本文介绍了Qt如何删除对象?存储 QObjects 的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

听说Qt中的对象会自动删除它们的子对象,我想知道在那些情况下会发生什么.

I heard that objects in Qt will automatically delete their children, I want to know what will happen in those situations.

#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在销毁一个孩子时会做什么?

Is this allowed in Qt? What does Qt do when destroying a child ?

顺便说一句,我考虑过使用诸如 shared_ptr 之类的智能指针.但我认为Qt也会删除已经被智能指针销毁的对象.

BTW, I considered using smart pointers such as shared_ptr. But I think Qt would also delete the object which had already been destroyed by smart pointer too.

我知道您想使用 new 为对象分配动态内存.但是我觉得不放心,请问在依赖Qt的对象树处理动态内存时,有没有什么情况(例如异常)会导致内存泄漏?

I know you would like to use new to allocate dynamic memory for objects. But I don't feel its reassuring, please tell me if there are any situations (e.g. exceptions) that will lead to memory leaks when relying on Qt's object tree to handle dynamic memory?

如果我使用对象而不是指针来动态分配对象,我必须考虑对象的销毁顺序,只要它们有所有权,这很繁琐.我不知道在 Qt 中使用动态内存是否是一个好习惯.

If I use objects rather than pointers to dynamically allocate objects, I have to consider the order of destruction of objects as long as they have ownership, which is tedious. I don't know whether it is good practice to use dynamic memory in Qt.

您有什么建议或更好的解决方案吗?

Do you have any suggestions or better solutions?

推荐答案

Composite 的 QObject 实现设计模式已经通过许多 Qt 版本的尝试和测试.

The QObject implementation of the Composite Design Pattern has been tried and tested through the many versions of Qt.

该模式要求复合对象拥有子对象的所有权,因此,只要父对象完成,您就可以放心,当父对象被销毁时,子对象 QObjects 将被销毁.

The pattern requires that the composite object takes ownership of the children so, as long as the parenting has been done, you can be assured that the child QObjects will be destroyed when the parent is destroyed.

标准做法是在堆内存中创建子对象并立即将它们作为父对象.如果您不立即父级,则可以使用 setParent() 函数显式父级,否则在您将小部件添加到父级小部件时,将自动完成父级,或者使用 addWidget()addLayout().

Standard practice is to create child objects in heap memory and parent them immediately. If you don't parent immediately, you can explicitly parent using the setParent() function, or else parenting will be done automatically when you add the widget to a parent widget, either using addWidget() or addLayout().

QLayout 对象是其他 QLayoutsQWidgets 的大小和布局管理器.他们不拥有他们管理的对象.父元素实际上是 QLayout 是其子元素的 QWidget.

QLayout objects are size and layout managers of other QLayouts and of QWidgets. They don't own the objects they manage. The parent is actually the QWidget that the QLayout is the child of.

您可以选择在堆栈内存或堆内存中创建根父级.

You have a choice to create the root parent in stack memory or in heap memory.

如果您对智能指针更满意,有两个类专门用于 QObjects:QPointerQSharedPointer.各有优缺点.

If you feel more comfortable with smart pointers, there are two classes that are specifically for QObjects: QPointer and QSharedPointer. Each has their pros and cons.

#include <QApplication>
#include <QLabel>
#include <QHBoxLayout>
#include <QWidget>

int main(int argc, char **argv)
{
    QApplication app(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
}

这篇关于Qt如何删除对象?存储 QObjects 的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆