[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 指针

相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
慧都小项1 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
CoderYanger1 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读1 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json
CCCCCCCCharlie1 天前
Linux进程控制四大核心操作
linux·开发语言