CRuntimeClass没有
基类。 每个由CObject派生的类都与一个CRuntimeClass结构相联系,用户可以使用该结构获取一个对象及其
基类的运行时信息。当需要额外的函数参数检查时,或当用户必须根据一个对象的类编写特殊目的代码时,在运行时确定该对象的类就非常有用。C++并不直接支持运行时类的信息。
CRuntimeClass是MFC实现的RTTI(运行时类型信息),MFC中的很多类需要由框架动态创建(比如文档、视图、框架窗口类等等),所以从CObject继承的类如果需要这种能力,必须实现它的CRuntimeClass,包括CreateObject静态方法(这个方法简单调用new CMyClass)。而做到这个很简单,使用DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏就自动拥有这个特性,看看这两个宏的定义就能理解其原理。
CRuntimeClass在MFC中定义为一个数据结构,在文件AFX.H中声明,它是用来串起MFC从COBJECT继承下来的所有类(相当于一根绳,只要你牵住绳的一头你就可以得到绳上的所有数据),你也可以把你自己写的类加入这根绳。
要使用CRuntimeClass结构,你必须在你想要获取运行时对象信息的类的实现中包括IMPLEMENT_DYNAMIC,IMPLEMENT_DYNCREATE,或IMPLEMENT_SERIAL宏。
CObject::GetRuntimeClass, CObject::IsKindOf, RUNTIME_CLASS, IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE, IMPLEMENT_SERIALCRuntimeClass在MFC中的作用很重要,因为MFC利用它来进行类的动态确定,即是通过
类变量来判定该变量是否为某一类的实例。由于
指针的类型是可以转换的,所以时常会出现从A到B的转换导致错误。而在MFC的各种书籍中对CRuntimeClass的介绍是比较少的,在这里总结它的一些用法。
在MFC中CObject::IsKindOf( const CRuntimeClass* pClass ) 利用CRuntimeClass来进行判定,如果你生成的类是以CObject为基础的,你可以使用该成员函数来判定。下面举一个例子来加深了解。
CObject CRuntimeClass::CreateObject(void)可以产生一个
类变量。作用和new类似,但在某些特殊场合有独特的作用。下面举一个例子来加深了解。
在上面例子中,CreateWnd返回的是CWnd* 其实它是一个CWndA*。你可以进行由子类到父类的强制转换而不必要担心出错。使用CRuntimeClass可以代替使用switch生产类实例的一些繁琐。(请好好想想它的用途,当你发现它的好处时,你一定会大吃一惊,M$使用宏来实现类的动态检测,如果谁有兴趣可以去看看MFC的源代码。)