rtti运行时类型识别与类对象的动态创建

上传人:第*** 文档编号:34064372 上传时间:2018-02-20 格式:DOC 页数:9 大小:176.50KB
返回 下载 相关 举报
rtti运行时类型识别与类对象的动态创建_第1页
第1页 / 共9页
rtti运行时类型识别与类对象的动态创建_第2页
第2页 / 共9页
rtti运行时类型识别与类对象的动态创建_第3页
第3页 / 共9页
rtti运行时类型识别与类对象的动态创建_第4页
第4页 / 共9页
rtti运行时类型识别与类对象的动态创建_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《rtti运行时类型识别与类对象的动态创建》由会员分享,可在线阅读,更多相关《rtti运行时类型识别与类对象的动态创建(9页珍藏版)》请在金锄头文库上搜索。

1、RTTI 运行时类型识别CRuntimeClass 是 MFC 专用的。CRuntimeClass 在文件 AFX.H 中声明,它是用来串起 MFC从 COBJECT 继承下来的所有类。也可以把自己写的类加入这个链表。struct CRuntimeClass/ AttributesLPCSTR m_lpszClassName; /类名int m_nObjectSize; /类对象大小UINT m_wSchema; /分类编号(对不可分类的类,该值为-1)CObject* (PASCAL* m_pfnCreateObject)(); / NULL = abstract classCRuntime

2、Class* m_pBaseClass; /基类指针,但这里指针一定是指向父亲的,而不会指向祖父/ CRuntimeClass objects linked together in simple liststatic CRuntimeClass* pFirstClass; / class list 的链表头。注意这个与基类指针不同。并且,该对象是个静态变量,所有 CRuntimeClass 对象共享CRuntimeClass* m_pNextClass; / 链表中紧跟当前对象的下一个对象。与当前对象不一定有继承关系;特别注意:该 struct 使用了链表的概念,但是该链表与常规的数据结构链表

3、是不太一样的。该链表每次新加入的节点都是放在链表头上的,类似栈。所以 pFirstClass 是随着每次新节点的加入一直在更新的,pFirstClass 必然指向新加入的节点。而 m_pNextClass 则指向前一个加入的节点。如下图:首先初始化 static CRuntimeClass* pFirstClass 为 NULL。 最开始加入链表的是 CObject。此时:在_IMPLEMENT_RUNTIMECLASS 宏中先直接设置 m_pBaseClass:#m_pBaseClass= NULL;然后在_IMPLEMENT_RUNTIMECLASS 宏中调用 AFX_CLASSINIT

4、的构造函数设置m_pNextClass 与 pFirstClass:(这两者是先 m_pNextClass 后 pFirstClass)#m_pNextClass= pFirstClass =NULL;#pFirstClass= CObject; 然后 CCmdTarget 加入链表。数据更新顺序同上:#m_pBaseClass=CObject;#m_pNextClass= pFirstClass = CObject;#pFirstClass= CCmdTarget; 接着 CWinThread 加入链表。数据更新顺序同上:#m_pBaseClass=CCmdTarget;#m_pNextCl

5、ass= pFirstClass = CCmdTarget;#pFirstClass= CWinThread;每一个类都拥有这样一个 static 的 CRuntimeClass 成员变量。由于每个类都有 static 的CRuntimeClass 成员变量,所以每个类的对象都是引用以及修改本类的 static 的CRuntimeClass 成员变量,而不会将父类或者子类的修改掉。 (父类与子类中的 static 同名成员变量是会造成“覆盖”的,该覆盖指的是引用时若不加域名直接使用,则使用的是本类的,而不会引用父类的。但实际上在内存中父类的 static 同名成员变量是依然存在的)每个 sta

6、tic 的 CRuntimeClass 成员变量都有一定的命名规则(在 CRuntimeClass 中采用的方法是在每个类的类名之前冠以class 作为它的名称,如 CView 的名称为 classCView) ,然后,经由某种手段将整个类别库构造好之后, 类别型录能呈现类似这样的风貌:注意是每个类共享一个 CRuntimeClass 成员变量。例:CCmdTarget cmd1,cmd2;CWinThread thread;上面两个类定义了三个对象。其中: cmd1 与 cmd2 共享一个 CRuntimeClass 成员变量。所以 cmd1 与 cmd2 所拥有的CRuntimeClass

7、 成员变量是同一个。 thread 单独使用一个 CRuntimeClass 成员变量。thread 所使用的这个 CRuntimeClass成员变量与 cmd1、cmd2 共享的那个 CRuntimeClass 成员变量不是同一个。 pFirstClass 是 CRuntimeClass 结构体中的 static 变量,所以所有的对象都共享pFirstClass。因此, cmd1、cmd2、thread 三者共享 CRuntimeClass 结构体中的 static变量 pFirstClass。对于 CView,其CView.hclass CView : public CWndDECLARE

8、_DYNAMIC(CView)CView.cppIMPLEMENT_DYNAMIC (CsdiTestView, CView)其中的两个宏 DECLARE_DYNAMIC 与 IMPLEMENT_DYNAMIC 展开后,代码如下:/*#define DECLARE_DYNAMIC(class_name) public: static CRuntimeClass class#class_name; virtual CRuntimeClass* GetRuntimeClass() const;#define IMPLEMENT_DYNAMIC(class_name, base_class_name

9、) _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)*/ 出现在宏定义之中的#,用来告诉编译器,把两个字符串系在一起。如果你这么使用此宏:DECLARE_DYNAMIC(CView)编译器前置处理器为你做出的码是:public:static CRuntimeClass classCView;/静态成员变量,所有该类对象都共享该变量virtual CRuntimeClass* GetRuntimeClass() const; IMPLEMENT_DYNAMIC 宏之中又使用了一个_IMPLEMENT_RUNTIM

10、ECLASS 宏,之所以这样做是因为_IMPLEMENT_RUNTIMECLASS 宏在动态创建时还要用到。_IMPLEMENT_RUNTIMECLASS 宏定义:/*#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name,wSchema,pfnNew) static char _lpsz#class_name = #class_name; CRuntimeClass class_name:class#class_name = _lpsz#class_name, sizeof(class_name), wSchema, pfnNe

11、w, RUNTIME_CLASS(base_class_name), NULL ; static AFX_CLASSINIT _init_#class_name( CRuntimeClass* class_name:GetRuntimeClass() const return */ 其中又有 RUNTIME_CLASS 宏,该宏用于取指定类的静态 CRuntimeClass 对象地址。由于在上面代码中调用该宏是 RUNTIME_CLASS(base_class_name), NULL ;所以传入的参数是 base_class_name,从而获取的地址是基类(即父类)的静态 CRuntimeCl

12、ass 对象地址。其定义如下:/*#define RUNTIME_CLASS(class_name) (&class_name:class#class_name)*/ 看起来整个 IMPLEMENT_DYNAMIC 内容好象只是指定初值,不然,其曼妙处在于它所使用的一个 struct AFX_CLASSINIT,定义如下:/*struct AFX_CLASSINIT AFX_CLASSINIT(CRuntimeClass* pNewClass); ;*/这表示它有一个构造函数(别惊讶,C+ 的 struct 与 class 都有构造式) ,定义如下:AFX_CLASSINIT:AFX_CLAS

13、SINIT(CRuntimeClass* pNewClass)pNewClass-m_pNextClass = CRuntimeClass:pFirstClass;CRuntimeClass:pFirstClass = pNewClass;很明显,此构造式负责 linked list 的串接工作。即将所有对象/ in header fileclass CView : public CWndDECLARE_DYNAMIC(CView).;/ in implementation fileIMPLEMENT_DYNAMIC(CView, CWnd)上述的码展开来成为:/ 头文件class CView

14、 : public CWndpublic:static CRuntimeClass classCView; virtual CRuntimeClass* GetRuntimeClass() const;/展开后定义了一个 CRuntimeClass 静态对象以及该对象的获取函数/静态成员变量 classCView,所有该类对象都共享该变量/获取函数在这里仅仅是声明,具体实现需要在 CPP 中进行.;/ 实现static char _lpszCView = CView;/CRuntimeClass 的第一个成员变量/注意这里定义了一个 static 的字符串,下面传参传入的就是这个字符串。这样做会使得所有的该类成员名称都相同CRuntimeClass CView:classCView = _lpszCView, sizeof(CView)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号