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

Qt是基于C++的跨平台图形界面(GUI)开发框架,简单说就是给C++开发者准备的"开发工具箱+底层封装库",让C++能高效做界面、写跨平台程序,不用为Windows/ Linux/ 嵌入式等系统单独写代码。

启用C++继承特性时,要让子类对象能使用父类对象的 this 指针,有点类似双内存空间链表链接。

  1. 子类需要调用父类的成员(非 Qt 对象树),直接分配指针对象,但是破坏了父子类之间的封装特性。如果两个类没有继承关系,只是想让子类持有父类的指针来调用方法,可以在子类中定义一个成员变量来保存父类的 this:

class ParentClass : public QObject {

Q_OBJECT

public:

void createChild() {

// 将父类自己的 this 传给子类

child = new ChildClass(this);

}

private:

ChildClass *child;

};

class ChildClass : public QObject {

Q_OBJECT

public:

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_cast<ParentClass*>(parent()) 转换,但每次都写麻烦,而且可能失败。保存 m_parent 更直接。

Q2:thismain 里能用吗?

  • 不能。main 函数不是类的成员函数,没有 this。所以示例最后一行中的 this 是错误的,应该改为 nullptr 或者一个真实存在的 QObject 指针。

  • 正确写法:

    cpp

    复制代码
    // 在 main 函数中
    ParentClass *parent = new ParentClass(nullptr);  // 顶层对象,无父对象
    ChildClass *child = new ChildClass(parent);

Q3:explicit 关键字有什么用?

  • 防止编译器自动隐式转换。比如你写 ChildClass child = parent; 会编译报错,必须显式写成 ChildClass child(parent);。这能避免不经意间的错误转换。

Q4:Q_OBJECT 宏是干嘛的?

  • 必须写在继承 QObject 的类的最开头,才能使用信号槽、动态属性等 Qt 特性。即使你暂时不用,也要写上,否则可能编译出错。
  1. new ParentClass(nullptr)

→ 调用 QObject(nullptr) 构造

→ ParentClass 构造完成

  1. new ChildClass(parent)

→ 调用 QObject(parent) 构造,设置 Qt 父子关系

→ 初始化 m_parent = parent

→ ChildClass 构造完成

  1. child->useParent()

→ 判断 m_parent 不为空

→ 调用 m_parent->parentMethod()

→ 打印信息

  1. 程序结束,delete parent

→ Qt 自动删除 parent 的所有子对象(包括 child)

→ 先析构 child,再析构 parent

  1. 利用 Qt 对象树(推荐),Qt 标准做法,能自动管理生命周期(父对象销毁时子对象也会被销毁),但获取时需要用 qobject_cast 转型。如果子类继承自 QObject,可以在构造时直接传入父对象的 this,Qt 会自动管理父子关系,子类可通过 parent() 获取父类指针:

class MyChild : public QObject {

Q_OBJECT

public:

explicit MyChild(QObject *parent = nullptr) : QObject(parent) {}

void useParent() {

// 通过 parent() 获取父对象,需转型为实际的父类类型

ParentClass *p = qobject_cast<ParentClass*>(parent());

if (p) {

p->parentMethod();

}

}

};

// 使用时

ParentClass *parent = new ParentClass(this);

MyChild *child = new MyChild(parent); // 自动保存 parent 指针

相关推荐
cui_ruicheng几秒前
Python从入门到实战(十五):文件操作与目录管理
开发语言·python
Roy_Sashulin5 分钟前
灵杉Java编程平台第一章:安装
java·开发语言
名字还没想好☜5 分钟前
Go 用 errgroup 管理并发子任务:错误收敛、取消传播与限流
开发语言·后端·golang·go·并发
2zcode35 分钟前
基于MATLAB深度卷积特征的多曝光图像自适应融合系统设计与实现
开发语言·matlab·多曝光图像自适应融合系统
hold?fish:palm1 小时前
7 接雨水
开发语言·c++·leetcode
geats人山人海2 小时前
c# 第九章 record
开发语言·c#
早期的虫儿有鸟吃2 小时前
vue2--Vuex 模块化
开发语言·前端·javascript
浪客川2 小时前
Android的SystemUI的启动流程简析
android·开发语言
房开民2 小时前
Qt TCP 服务器开发实战:与 VisionMaster OCR 通信
服务器·qt·tcp/ip
-银雾鸢尾-3 小时前
C#中的抽象类与抽象方法
开发语言·c#