Qt 中的内存管理? ?

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

在下面的例子中,我创建的对象中哪些需要删除?如果 myClass被摧毁,实例变量会发生什么变化?如果我根本不删除(或销毁)我的对象会发生什么?这会影响记忆吗?

MyClass.h

class MyClass
{


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

MyClass.cpp

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


MyOtherClass myOtherClass2;


QString myString = "Hello";
}

正如你所看到的,这是相当新手容易的东西,但我在哪里可以学习这一容易的方式?

63499 次浏览

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

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

then it is enough to delete the 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 child manually before the parent.)

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

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

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) QObject will suffice.

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 QObject as a parent.

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* 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://www.qt.io/blog/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have

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.

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.

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