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

相关推荐
程与留11 小时前
15_国际化和本地化:tr()、ts 文件、QM 文件、多语言切换
c++·qt
程与留12 小时前
14_Qt 样式表(QSS)入门(语法、选择器、美化实战)
c++·qt
Quz19 小时前
QML 拖拽篇:接收拖拽与数据交换
qt
Interview Aid11221 小时前
TikTok OA 四题分享|半小时内 AC,题目基本都是实现题
java·开发语言·算法·面试·职场和发展
CoderIsArt1 天前
C#中UI 线程与 Dispatcher
开发语言·ui·c#
AI情绪识别开源1 天前
检信 ALLEMOTION OS 加密打包可执行程序 — 全面测试报告版本: v1.3功能测试 / 性能测试 /
开发语言·数据结构·人工智能·功能测试
「QT(C++)开发工程师」1 天前
C++ auto 用法详解
开发语言·c++
OPEN-F1 天前
C++STL教程:容器适配器与实用工具
开发语言·c++
yaoxin5211231 天前
507. Java 反射 - 在 BeanFactory 中实现依赖注入
java·开发语言