問題描述
聽說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
對象是其他 QLayouts
和 QWidgets
的大小和布局管理器.他們不擁有他們管理的對象.父元素實際上是 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
:QPointer 和 QSharedPointer.各有優缺點.
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 的最佳方式是什么?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!