C++ Qt中的内存管理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2491707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:39:15  来源:igfitidea点击:

Memory management in Qt?

c++qtmemoryobject

提问by Martin

I'm quite new to Qt and am wondering on some basic stuff with memory management and the life of objects. When do I need to delete and/or destroy my objects? Is any of this handled automatically?

我对 Qt 很陌生,我想知道一些关于内存管理和对象生命周期的基本知识。我什么时候需要删除和/或销毁我的对象?这些都是自动处理的吗?

In the example below, which of the objects I create do I need to delete? What happens to the instance variable myOtherClasswhen myClassis destroyed? What happens if I don't delete (or destroy) my objects at all? Will that be a problem to memory?

在下面的示例中,我创建的哪些对象需要删除?实例变量被销毁myOtherClass时会发生什么myClass?如果我根本不删除(或销毁)我的对象会发生什么?那会不会是内存问题?

MyClass.h

我的类.h

class MyClass
{

public:
    MyClass();
    ~MyClass();
    MyOtherClass *myOtherClass;
};

MyClass.cpp

我的类.cpp

MyClass::MyClass() {
    myOtherClass = new MyOtherClass();

    MyOtherClass myOtherClass2;

    QString myString = "Hello";
}

As you can see this is quite newbie-easy stuff but where can I learn about this in an easy way?

正如您所看到的,这是非常容易上手的东西,但是我在哪里可以轻松地了解它?

回答by Debilski

If you build your own hierarchy with QObjects, that is, you initialise all newly created QObjects with a parent,

如果您使用QObjects构建自己的层次结构,即QObject使用父级初始化所有新创建的s,

QObject* parent = new QObject();
QObject* child = new QObject(parent);

then it is enough to deletethe parent, because the parents destructor will take care of destroying child. (It does this by issuing signals, so it is safe even when you delete childmanually before the parent.)

那么就够deleteparent,因为parents析构函数会负责销毁child。(它通过发出信号来做到这一点,因此即使您child在父级之前手动删除也是安全的。)

You could also delete the child first, the order doesn't matter. For an example where the order doesmatter here's the documentation about object trees.

您也可以先删除孩子,顺序无关紧要。例如,这里的顺序确实很重要,这是关于对象树的文档

If your MyClassis not a child of QObject, you'll have to use the plain C++ way of doing things.

如果您MyClass不是 的孩子QObject,则必须使用普通的 C++ 做事方式。

Also, note that the parent–child hierarchy of QObjects is generally independent of the hierarchy of the C++ class hierarchy/inheritance tree. That means, that an assigned child does not need to be a direct subclass of it's parent. Any (subclass of) QObjectwill suffice.

另外,请注意QObjects的父子层次结构通常独立于 C++ 类层次结构/继承树的层次结构。这意味着,分配的 child 不需要是其 parent 的直接子类。任何(的子类)QObject就足够了。

There might be some constraints imposed by the constructors for other reasons, however; such as in QWidget(QWidget* parent=0), where the parent must be another QWidget, due to e.g. visibility flags and because you'd do some basic layout that way; but for Qt's hierarchy system in general, you are allowed to have any QObjectas a parent.

但是,由于其他原因,构造函数可能会施加一些限制;例如 in QWidget(QWidget* parent=0),其中父级必须是 another QWidget,因为例如可见性标志,并且因为您会以这种方式进行一些基本布局;但是对于 Qt 的一般层次结构系统,您可以将 anyQObject作为父级。

回答by Austin

I'd like to extend Debilski's answer by pointing out that the concept of ownership is very important in Qt. When class A assumes ownership of class B, class B is deleted when class A is deleted. There are several situations where one object becomes the owner of another, not just when you create an object and specify its parent.

我想通过指出所有权的概念在 Qt 中非常重要来扩展 Debilski 的回答。当 A 类承担 B 类的所有权时,当 A 类被删除时,B 类也被删除。在多种情况下,一个对象成为另一个对象的所有者,而不仅仅是在您创建对象并指定其父对象时。

For instance:

例如:

QVBoxLayout* layout = new QVBoxLayout;
QPushButton someButton = new QPushButton; // No owner specified.
layout->addWidget(someButton); // someButton still has no owner.
QWidget* widget = new QWidget;
widget->setLayout(layout); // someButton is "re-parented".
                           // widget now owns someButton.

Another example:

另一个例子:

QMainWindow* window = new QMainWindow;
QWidget* widget = new QWidget; //widget has no owner
window->setCentralWidget(widget); //widget is now owned by window.

So, check the documentation often, it generally specifies whether a method will affect the ownership of an object.

因此,经常查看文档,它通常指定一个方法是否会影响对象的所有权。

As stated by Debilski, these rules apply ONLY to objects that derive from QObject. If your class does not derive from QObject, you'll have to handle the destruction yourself.

正如 Debilski 所说,这些规则仅适用于从 QObject 派生的对象。如果您的类不是从 QObject 派生的,则您必须自己处理销毁。

回答by yesraaj

Parent(either QObject object or its derived class) has a list of pointer to its children(QObject/its derived). The parent will delete all the objects in its child list while the parent is destroyed. You can use this property of QObject to make child objects to delete automatically when ever the parent is deleted. The relation can be established using the following code

父对象(QObject 对象或其派生类)有一个指向其子对象(QObject/其派生类)的指针列表。当父对象被销毁时,父对象将删除其子列表中的所有对象。您可以使用 QObject 的此属性使子对象在删除父对象时自动删除。可以使用以下代码建立关系

QObject* parent = new QObject();
QObject* child = new QObject(parent);
delete parent;//all the child objects will get deleted when parent is deleted, child object which are deleted before the parent object is removed from the parent's child list so those destructor will not get called once again.

There are other way to manage memory in Qt, using smartpointer. The following article describes various smart pointers in Qt. https://blog.qt.digia.com/blog/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have/

在 Qt 中还有其他管理内存的方法,使用智能指针。下面的文章介绍了 Qt 中的各种智能指针。 https://blog.qt.digi.com/blog/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have/

回答by Khaled

To add on to these answers, for vérification, I would recommend you to utilize Visual Leak Detetorlibrary for your Visual c++ projets, including Qt projects since its based on c++, this library is compatible with new, delete, free and mallocstatements, it is well documented and easy to use. Don't forget that when you create your own QDialogor QWidgetinherited interface class, and then create a new object of this class, don't forget to execute setAttribute(Qt::WA_DeleteOnClose)function of your object.

要补充这些答案,为了验证,我建议您将Visual Leak Detetor库用于 Visual c++ 项目,包括 Qt 项目,因为它基于 c++,该库与new, delete, free and malloc语句兼容,文档齐全且易于使用。不要忘记,当您创建自己的QDialogQWidget继承的接口类,然后创建该类的新对象时,不要忘记执行setAttribute(Qt::WA_DeleteOnClose)您对象的功能。