http://blog.csdn.net/ligand/article/details/49839507

MFC运行时类信息

用途:

程序在运行时,获取对象类的信息及类的继承关系
 

实现:

1、定义的类必须继承自CObject类。
2、类内声明宏DECLARE_DYNAMIC(),类外实现宏IMPLEMENT_DYNAMIC()
3、使用:
  1. BOOL CObject::IsKindOf(CRuntimeClass* pClass)//对象是否属于某个类
  2. CRuntimeClass* GetRuntimeClass( );//获取对象运行时类信息,经常使用RUNTIME_CLASS(类名)代替。

示例:

  1. class CAnimal:public CObject
  2. {
  3. DECLARE_DYNAMIC(CAnimal)
  4. };
  5. IMPLEMENT_DYNAMIC(CAnimal,CObject)
  6. class CDog:public CAnimal
  7. {
  8. DECLARE_DYNAMIC(CDog)
  9. };
  10. IMPLEMENT_DYNAMIC(CDog,CAnimal)
  11. int main(int argc, char* argv[])
  12. {
  13. printf("Hello World!\n");
  14. CDog dog;
  15. if(dog.IsKindOf(RUNTIME_CLASS(CAnimal)))
  16. {
  17. printf("dog is an animal\n");
  18. }
  19. CAnimal animal;
  20. CRuntimeClass* rt=animal.GetRuntimeClass();
  21. printf("运行时类信息,类名:%s,大小:%d,版本:%d\n",rt->m_lpszClassName,rt->m_nObjectSize,rt->m_wSchema);
  22. if(animal.IsKindOf(rt))
  23. {
  24. printf("animal is an animal\n");
  25. }
  26. return 0;
  27. }

动态创建对象

作用和意义:

 一般编程时,使用系统的类定义对象,调用对象的成员函数完成相关的功能。有了动态创建,由用户定义类,系统函数创建该类的对象,由底层代码创建上层类的对象。
 

实现:

1、定义类必须继承自CObject类。
2、类内声明宏DECLARE_DYNCREATE,类外实现宏IMPLEMENT_DYNCREATE
3、使用:

实例:

  1. class CAnimal:public CObject
  2. {
  3. DECLARE_DYNCREATE(CAnimal)
  4. };
  5. IMPLEMENT_DYNCREATE(CAnimal,CObject)
  1. class CDog:public CAnimal
  2. {
  3. DECLARE_DYNCREATE(CDog)
  4. };
  5. IMPLEMENT_DYNCREATE(CDog,CAnimal)
  1. //定义动态创建对象的函数
  2. void CreateInstance(CRuntimeClass* pClass)
  3. {
  4. CObject *pObj=pClass->CreateObject();
  5. printf("对象地址:%p\n",pObj);
  6. printf("类名:%s\n",pClass->m_lpszClassName);
  7. delete pObj;
  8. }
  1. int main(int argc, char* argv[])
  2. {
  3. printf("Hello World!\n");
  4. CreateInstance(RUNTIME_CLASS(CDog));
  5. return 0;
  6. }

具体实现细节

类继承体系中每个类都定义一个CRuntimeClass类型的静态数据成员,并定义静态成员函数 _GetBaseClass、GetThisClass及虚函数GetRuntimeClass。

    1. struct CRuntimeClass
    2. {
    3. // Attributes
    4. LPCSTR m_lpszClassName;
    5. int m_nObjectSize;
    6. UINT m_wSchema; // schema number of the loaded class
    7. CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
    8. #ifdef _AFXDLL
    9. CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
    10. #else
    11. CRuntimeClass* m_pBaseClass;
    12. #endif
    13. // Operations
    14. CObject* CreateObject();
    15. BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
    16. // dynamic name lookup and creation
    17. static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);//搜AfxGetModuleState()->m_classList,如果不成功再search classes in shared DLLs, 即pModuleState->m_libraryList->m_classList
    18. static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
    19. static CObject* PASCAL CreateObject(LPCSTR lpszClassName);//从类名字符串,用FromName返回对应的CRuntimeClass,然后调用CRuntimeClass的成员函数CreateObject()
    20. static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);
    21. // Implementation
    22. void Store(CArchive& ar) const;
    23. static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);//从CArchive读入类名字符串,然后返回对应的CRuntimeClass的对象。
    24. // CRuntimeClass objects linked together in simple list
    25. CRuntimeClass* m_pNextClass;       // linked list of registered classes
    26. const AFX_CLASSINIT* m_pClassInit;
    27. };

MFC中关于运行时类信息及动态创建对象的两个宏的意义(转)的更多相关文章

  1. 在Amazon FreeRTOS V10中使用运行时统计信息

    在MCU on Eclipse网站上看到Erich Styger在8月2日发的博文,一篇关于在Amazon FreeRTOS V10中使用运行时统计信息的文章,本人觉得很有启发,特将其翻译过来以备参考 ...

  2. Visual C++中对运行时库的支持

    原文地址:http://blog.csdn.net/wqvbjhc/article/details/6612099 一.什么是C运行时库 1)C运行时库就是 C run-time library,是 ...

  3. Java:日历类、日期类、数学类、运行时类、随机类、系统类

    一:Calendar类 java.util 抽象类Calendar   1.static Calendar getInstance()使用默认时区和语言环境获得一个日历. 2. int get(int ...

  4. 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别

    运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...

  5. 【JavaSE】运行时类型信息(RTTI、反射)

    运行时类型信息使得你可以在程序运行时发现和使用类型信息.--<Think in java 4th> **** 通常我们在面向对象的程序设计中我们经常使用多态特性使得大部分代码尽可能地少了解 ...

  6. [C++]C++中的运行时类型检测

    Date:2014-1-3 Summary: 使用C++中的运行时类型检测.(文章重点在于记录本人的使用情况,并非深层讨论RTTI) Contents:写习惯C#的我,在C++依然存在哪些.NET的惯 ...

  7. 翻译:JVM虚拟机规范1.7中的运行时常量池部分(二)

    本篇为JVM虚拟机规范1.7中的运行时常量池部分系列的第二篇. 4.4.4. The CONSTANT_Integer_info and CONSTANT_Float_info Structures ...

  8. java 面向对象(四十二):反射(六)反射应用三:调用运行时类的指定结构

    调用指定的属性: @Test public void testField1() throws Exception { Class clazz = Person.class; //创建运行时类的对象 P ...

  9. java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构

    我们可以通过反射,获取对应的运行时类中所有的属性.方法.构造器.父类.接口.父类的泛型.包.注解.异常等....典型代码: @Test public void test1(){ Class clazz ...

随机推荐

  1. TP5.0 Redis(单例模式)(原)

    看到好多面试都问设计模式,我就简单的了解了一下,顺便把之前封装好的Reis做了一次修改. 单例模式(Singleton Pattern 单件模式或单元素模式) 单例模式确保某个类只有一个实例,而且自行 ...

  2. 常用adb 指令

    adb指令 monkey https://www.cnblogs.com/aland-1415/p/6949964.html

  3. textarea右下角黑点

    先记录问题及解决方法,原因后续深入了解 在布局中,用到了textarea 输入框,在Android手机上却显示右下角有一个黑点,检查代码无误,代码没有多余的点符号. 解决:在textarea 中添加 ...

  4. echarts 自适应方法 x和y x2和y2

    grid:{ x:65, y:20, x2:30, y2:30},

  5. 关于memset函数--赋最大值

    问题起源: 这几天在刷CCF的时候,图论那边经常用到赋最大值,一开始自己一直手工for循环赋值(INT_MAX或者是LONG_LONG_MAX),后来看到别人的代码,发现了一个比较高端的赋值  mem ...

  6. 北航OO第二单元总结

    电梯调度的设计策略 第一次作业是单部多线程傻瓜电梯 这次作业的电梯名副其实是一部傻瓜电梯,每次只能运一个人.出于线程安全的考虑,选择了阻塞队列.然后按照先来先服务的原则服务下一个指令.没有什么复杂的设 ...

  7. java入门day04-方法简述

    方法: 是完成特定功能(一个)的代码集合,这些特定功能的代码可以被重复使用. 修饰符  方法返回值类型  方法名(形参列表){  方法体  }return 返回值: 形如: public static ...

  8. P1403 [AHOI2005]约数研究 题解

    转载luogu某位神犇的题解QAQ 这题重点在于一个公式: f(i)=n/i 至于公式是怎么推出来的,看我解释: 1-n的因子个数,可以看成共含有2因子的数的个数+含有3因子的数的个数……+含有n因子 ...

  9. 关于Apache的配置方法和步骤

    一.下载.安装和卸载 网址:https://httpd.apache.org/docs/current/platform/windows.html#down 点击ApacheHaus,在里面下载任何版 ...

  10. 定义一个Map集合,key和value不规定类型,任意放入数据,用keySet()和 entrySet()两种方式遍历出Map集合的数据

    package com.lanxi.demo1_1_1; import java.util.HashMap; import java.util.Iterator; import java.util.M ...