Qt 源码分析之元对象系统(一)

本文介绍了Qt元对象系统,它是对标准C++的扩展,旨在简化开发。通过元对象系统,可以动态获取类信息,例如类名、成员函数数量等。文章通过一个例子展示了如何利用moc.exe工具自动生成接口,避免大量手动修改代码,同时解答了关于Qt元对象系统的一些疑问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Qt 源码分析之元对象系统(一)

一、元对象系统

简单来说 Qt 元对象系统是对标准 C++ 的扩展。相比较其他高级语言java、python、php等,标准 C++ 为你做的工作实在是太少了,这样就使得开发人员写 C++ 很累,累的像 XXX 一样。特别是用 C++ 开发界面程序,那叫一个痛苦(这是针对大型软件)。

怎么办呢?既然标准不去做,那就让 Qt 来做吧,于是乎就诞生了 Qt 元对象系统。

一句话总结:Qt 元对象系统是为了方便程序开发,而对标准 C++ 做的扩展

二、举例

比如我们用 C++ 写了一个类 CMathEx,这个类是对标准数学类的扩展,我们给这个类添加查找 3 个整数中最大值的函数,如下:

#define max(x, y) (x) > (y) ? (x) : (y)

class CMathEx
{
	public:
	CMathEx()
	{
		
	}
	~CMathEx()
	{
		
	}
	int Max(int a, int b, int c)
	{
	    return max(max(a, b), c);
	}
};

然后我们定义一个 CMathEx 类对象 m,就可以调用 Max 函数了,如下:

CMathEx m;
m.Max(1, 99, 88);

采用如上方式你写了 n 多年。人算不如天算啊,问题来了,随着你编写的软件系统越来越庞大、架构越来越复杂、类和类对象也越来越多,为了保持软件系统的可升级和可维护性,CTO 要求增加动态获取自定义类的类信息的功能,比如对象所属类的名字、类中有几个成员函数、类中有几个属性等等。

怎么办呢?只见你灵机一动,这还不简单,给我们自定义的类增加上一些接口就不就可以了吗。

经过 5 分钟改造后的CMathEx如下:

#define max(x, y) (x) > (y) ? (x) : (y)

class CMathEx
{
	public:
	CMathEx()
	{
		
	}
	~CMathEx()
	{
		
	}
	const char * ClassName()
	{
	    return "CMathEx";
	}
	int Max(int a, int b, int c)
	{
	    return max(max(a, b), c);
	}
};

感觉自己真是聪明绝顶,这么简单就解决了 CTO 苦思冥想、夜不能寐的问题。兴致勃勃的你去软件系统里面查了查,发现大大小小一共有几千个类,哇塞,怎么办?

似乎你能想到的办法只要一个,就是一个类一个类的去修改。如果这样做整个软件系统从底层到上层要修改一遍,再加上修改后还需要测试,没有半年是搞不定的。

在这里插入图片描述
接下来怎么办?你也不知道,你也不敢问……

直到你遇到了 Qt 元对象系统,如同久旱逢甘霖呀。
重复的工作为什么要自己做呀,我们单独开发一个小工具 moc.exe ,让它读取要修改的文件,自动增加上我们想要扩展的函数接口,岂不妙哉!

在这里插入图片描述

到此相信你有很多个问号,不要着急往下看。

三、问题解答

问题 1、

细心的老鸟已经发现,为什么 Qt 元对象系统没有修改 xxxxxx.h xxxxxx.cpp 原始的两个文件,而是增加了一个moc_xxxxxx.cpp 新文件呢?

原因也不难想,如果修改了原始的文件,出了问题算谁的呢?Qt 为啥要去招惹这个麻烦呢(老鸟们都应该深有体会吧)。

问题 2、

增加一个接口不应该是同时修改 xxxxxx.hxxxxxx.cpp 吗?

是的。因为增加的接口是统一的接口,所以 Qt 是通过来修改 xxxxxx.h ,举例说明:

原始的文件如下:

/*
    CMathEx.h
*/
#define max(x, y) (x) > (y) ? (x) : (y)

class CMathEx
{
    public:
    CMathEx();
    ~CMathEx();
	
    int Max(int a, int b, int c);
};


/*
    CMathEx.cpp
*/
#include "CMathEx.h"

CMathEx::CMathEx()
{
}

CMathEx::~CMathEx()
{
}

int CMathEx::Max(int a, int b, int c)
{
    return max(max(a, b), c);
}

修改流程如下:
1、首先定义一个宏
(如果是在 Qt 中,这个宏是 Q_OBJECT)

#define OBJECT_EX \
public: \
    const char * ClassName(); \

2、在需要修改的类头文件中增加宏

/*
    CMathEx.h
*/
#define max(x, y) (x) > (y) ? (x) : (y)

class CMathEx
{
	OBJECT_EX

	public:
	CMathEx();
	~CMathEx();
	
	int Max(int a, int b, int c);
};

3、使用 moc.exe 处理包含宏的头文件

/*
    moc_CMathEx.cpp
*/
#include "CMathEx.h"

const char * CMathEx::ClassName()
{
    return "CMathEx";
}

四、总结

本篇文章简单介绍了 Qt 元对象系统的原理,具体实现细节还有很多,会陆续写出来分享,请大家点击关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大鹏068

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值