auther: abinng date: 2026-03-18 19:52
createDate:2026-03-18 19:51
主要逻辑
Qt
控件都会有一个父对象指针,依附于一个父对象,一旦父对象释放,父对象所有的子对象都会被自动析构,如下图:

当任何一个
QObject(不管是父是子)被销毁(调用析构函数)时,它会自动做两件事:
向下看(作为父对象):
遍历自己的子对象列表(Children List),对里面所有的子对象执行
delete 操作。
向上看(作为子对象): 通过 parent
指针找到自己的父对象,告诉父对象:“我要死了,请把我从你的子对象列表中移除掉。”(如果不做这一步,父对象以后析构时就会
delete 一个野指针导致崩溃)。
所以,无论你是手动 delete
了一个子对象,还是父对象被销毁引发了连锁反应,Qt
的这套机制都能保证内存安全。
在栈上创建对象时,会有释放顺序,如果先释放了父对象,再释放子对象,就会导致子对象多次释放,出错。所以一般会最上层的控件定义在栈上,下面管理的子控件申请在堆上
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <iostream> #include <QApplication> #include <string>
using std::cout; using std::endl;
class Abinng : public QObject { Q_OBJECT public: explicit Abinng(QObject *parent = nullptr) : QObject(parent) { cout <<__PRETTY_FUNCTION__ << endl; } ~Abinng() override { cout << __PRETTY_FUNCTION__ << endl; } };
class AbinngBlog : public QObject { Q_OBJECT public: explicit AbinngBlog(QObject *parent = nullptr) : QObject(parent) { cout << __PRETTY_FUNCTION__ << endl; } ~AbinngBlog() override { cout << __PRETTY_FUNCTION__ << endl; } };
void test01() { QObject root; Abinng *a1 = new Abinng(&root); AbinngBlog *ab1 = new AbinngBlog(a1); }
void badExample() { QObject child; QObject parent; child.setParent(&parent); }
int main(int argc, char *argv[]) { QApplication a(argc, argv);
test01(); return 0;
}
|