详解MFC运行时类信息机制

作用

在程序运行过程中可以获知对象的类的相关信息(例如对象是否属于某个类)

使用条件

  1. 类派生自CObject
  2. 类内添加声明宏 DECLARE_DYNAMIC(theClass)
  3. 类外添加实现宏 IMPLEMENT_DYNAMIC(theClass, baseClass)

使用方式

类对象名.IsKindOf(RUNTIME_CLASS(想要判断是否在其中的类名))

使用代码示例

//掐头
class CMonster:public CObject
{
    DECLARE_DYNAMIC(CMonster)
};
IMPLEMENT_DYNAMIC(CMonster, CObject)

int main()
{
    CMonster Shrem;
    if(shrem.IsKindOf(RUNTIME_CLASS(CMonster)))
    {
        std::cout << "Shrem is Monster" << std::endl;
    }
    else
    {
        std::cout << "Shrem is not Monster" << std::endl;
    }    
}
//去尾

你如果没有需求的话就不用往下看原理了,挺绕的

原理

把我们在上述代码中书写的宏展开后,其实就相当于在类内添加了public属性的一个静态变量(结构体)和一个虚函数

static const CRuntimeClass classCMonster;

virtual CRuntimeClass* GetRuntimeClass() const

静态变量和虚函数返回值都牵扯到CRunTimeClass结构体

CRunTimeClass详细介绍去MSDN查看,此处只介绍成员变量

 运行时类信息机制能用到的CRunTimeClass结构体的成员变量就只有前三个

        本类的CRunTimeClass结构体的第三成员指针指向父类的CRunTimeClass结构体,层层继承之下,每个类的CRunTimeClass成员的指针都指向父类结构体,于是就形成了一个链表,最子类的结构体就是链表头,CObject类(最基类)的CRunTimeClass成员就是链表尾,且其CRunTimeClass的第三成员指针为NULL。

virtual CRuntimeClass* GetRuntimeClass() const函数的作用

返回本函数所在类的CRunTimeClass静态变量的地址

RUNTIME_CLASS宏的作用

RUNTIME_CLASS代换内容如下:

//RUNTIME_CLASS(CMonster)
//↓↓↓↓↓↓↓↓
((CRuntimeClass*)(&CMonster::classCMonster))

可以看出,RUNTIME_CLASS的作用即得到参数传递的类对象的CRunTimeClass静态变量的地址

IsKindOf函数执行流程

IsKindOf函数定义:BOOL CObject::IsKindOf(const CRuntimeClass*pClass) const

1. 参数RUNTIME_CLASS(CObject)能够拿到CObject类的CRunTimeClass成员地址

2. 调用本类的GetRuntiomClass虚函数,将链表头地址保存到pClassThis中

3. 函数最后pClassThis -> IsDerivedFrom(pClass),调用IsDerivedFrom函数

4. 在IsDerivedFrom函数内部有一个循环,从链表头开始遍历链表寻找是不是有个节点的地址跟传参的地址一样,有的话返回true,没有返回false,继而IsKindOf也会根据IsDerivedFrom的返回值返回。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值