ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

[QT]Qt对象树笔记:父子关系与内存管理

[QT]Qt对象树笔记:父子关系与内存管理 Qt是基于C的跨平台图形界面GUI开发框架简单说就是给C开发者准备的“开发工具箱底层封装库”让C能高效做界面、写跨平台程序不用为Windows/ Linux/ 嵌入式等系统单独写代码。启用C继承特性时要让子类对象能使用父类对象的 this 指针有点类似双内存空间链表链接。1. 子类需要调用父类的成员非 Qt 对象树直接分配指针对象但是破坏了父子类之间的封装特性。如果两个类没有继承关系只是想让子类持有父类的指针来调用方法可以在子类中定义一个成员变量来保存父类的 thisclass ParentClass : public QObject {Q_OBJECTpublic:void createChild() {// 将父类自己的 this 传给子类child new ChildClass(this);}private:ChildClass *child;};class ChildClass : public QObject {Q_OBJECTpublic:explicit ChildClass(ParentClass *parent nullptr): QObject(parent), m_parent(parent) {}void useParent() {if (m_parent) {m_parent-parentMethod(); // 调用父类方法}}private://创建私有父类指针用于调用父类方法ParentClass *m_parent;};// 使用时ParentClass *parent new ParentClass(this);MyChild *child new MyChild(parent); // 自动保存 parent 指针Q1为什么要保存m_parent直接用parent()不行吗parent()返回的是QObject*只能调用QObject的方法。而你想调用ParentClass特有的parentMethod()所以需要ParentClass*类型的指针。你可以用qobject_castParentClass*(parent())转换但每次都写麻烦而且可能失败。保存m_parent更直接。Q2this在main里能用吗不能。main函数不是类的成员函数没有this。所以示例最后一行中的this是错误的应该改为nullptr或者一个真实存在的QObject指针。正确写法cpp// 在 main 函数中 ParentClass *parent new ParentClass(nullptr); // 顶层对象无父对象 ChildClass *child new ChildClass(parent);Q3explicit关键字有什么用防止编译器自动隐式转换。比如你写ChildClass child parent;会编译报错必须显式写成ChildClass child(parent);。这能避免不经意间的错误转换。Q4Q_OBJECT宏是干嘛的必须写在继承QObject的类的最开头才能使用信号槽、动态属性等 Qt 特性。即使你暂时不用也要写上否则可能编译出错。1. new ParentClass(nullptr)→ 调用 QObject(nullptr) 构造→ ParentClass 构造完成2. new ChildClass(parent)→ 调用 QObject(parent) 构造设置 Qt 父子关系→ 初始化 m_parent parent→ ChildClass 构造完成3. child-useParent()→ 判断 m_parent 不为空→ 调用 m_parent-parentMethod()→ 打印信息4. 程序结束delete parent→ Qt 自动删除 parent 的所有子对象包括 child→ 先析构 child再析构 parent2. 利用 Qt 对象树推荐Qt 标准做法能自动管理生命周期父对象销毁时子对象也会被销毁但获取时需要用 qobject_cast 转型。如果子类继承自 QObject可以在构造时直接传入父对象的 thisQt 会自动管理父子关系子类可通过 parent() 获取父类指针class MyChild : public QObject {Q_OBJECTpublic:explicit MyChild(QObject *parent nullptr) : QObject(parent) {}void useParent() {// 通过 parent() 获取父对象需转型为实际的父类类型ParentClass *p qobject_castParentClass*(parent());if (p) {p-parentMethod();}}};// 使用时ParentClass *parent new ParentClass(this);MyChild *child new MyChild(parent); // 自动保存 parent 指针
返回列表