新公司维护基于CAD的二次开发旧代码。学习ObjectARX相关的内容。

先看原始代码

class MyClass: public AcRxObject
{
public:virtual AcRxClass* isA() const{if (MyClass::gpDesc != NULL)return MyClass::gpDesc; return MyClass::gpDesc= (AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#MyClass));}static AcRxClass* gpDesc;static AcRxClass* desc(){if (MyClass::gpDesc != NULL)return MyClass::gpDesc;return MyClass::gpDesc = (AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->at(ACRX_CLASS_DICTIONARY))->at( ACRX_T(#MyClass) );}static MyClass* cast(const AcRxObject* inPtr){ return ((inPtr == NULL) || !inPtr->isKindOf(MyClass::desc()))? NULL : (MyClass*)inPtr; }
#if 0   //第一套方案static void rxInit(){    if (MyClass::gpDesc) {AcRxClass *pClass =(AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#MyClass));if (pClass) {if (MyClass::gpDesc == pClass)return;elseacrx_abort(ACRX_T(/*MSGO*/"Class mismatch"));}}MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#MyClass));}static void rxInit(AppNameChangeFuncPtr);#elsestatic AcRxObject * make##MyClass() { return new MyClass(); } \void rxInit() {if (MyClass::gpDesc) {AcRxClass *pClass =(AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#MyClass));if (pClass) {if (MyClass::gpDesc == pClass)return;elseacrx_abort(ACRX_T(/*MSGO*/"Class mismatch"));}}MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#PARENT_CLASS),VERNO, &make##MyClass);}#endifstatic AcRxObject * make##MyClass() { return new MyClass(); }
void MyClass::rxInit()
{ACRX_STATIC_CHECK(MyClass);MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#PARENT_CLASS),DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, &make##MyClass, ACRX_T(#DXF_NAME), ACRX_T(#APP));
}
void MyClass::rxInit(AppNameChangeFuncPtr ptr) {ACRX_STATIC_CHECK(MyClass);MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#PARENT_CLASS),DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, &make##MyClass, ACRX_T(#DXF_NAME), ACRX_T(#APP), ptr);
}};
AcRxClass* MyClass::gpDesc = NULL;inline bool AcRxObject::isKindOf(const AcRxClass* pOtherClass) const
{const AcRxClass * pMyClass = this->isA();return pMyClass == NULL ? false : pMyClass->isDerivedFrom(pOtherClass);}
void test( )
{AcDbEntity *pEnt...;if(pEnt->isA()==AcDbLine::desc()){//实体正好是一条线段}if(pEnt->isKindOf(AcDbLine::desc()) {AcDbLine* pLine = AcDbLine::cast(pEnt); //要判断实体是线段或者线段的派生对象}}

实现原理:

AcRxObject类及其派生类的静态成员gpDesc(AcRxClass类型)存储了运行时信息,在加载过程中完成初始化,同时会将此类注册到ObjectARX也会加入到系统的acrxClassDictionary中。

AcRxObject中相关的成员函数:

desc(),static,返回AcRxObject类(及其派生类)的运行时类信息描述符(对象);

cast(),static,返回指定对象的运行时类信息对象,如果不是这个类(或其子类),返回NULL;

isKindOf (),判断指定对象是否属于这个类(或其派生类);

isA(),返回对象自己的运行时类信息描述符。

=============================================
AcRxClass是 AcRxObject类(及其派生类)的运行时类信息类。
AcRxClass保存了当前类及其父类的关系等相关数据
AcRxObject::isA 和AcRxObject::desc功能类似。
前者是多态性体现着,后者是类的静态数据(绝对).
前者用于动态创建的对象,后者用于得到具体类类型信息.
cast用于进行具体转换。
kindof调用isA,再从类型信息树中递归查询信息。
注意:cast中调用了isKindOf

ObjectARX运行时类信息实现原理相关推荐

  1. 【MFC学习】运行时类信息机制

    作用 在程序运行过程中可以获知对象的类的相关信息:机器知道 运行时类信息机制使用 类必须派生自CObject 类内必须添加声明宏 DECLARE_DYNAMIC(theClass) 类外必须添加实现宏 ...

  2. 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理

    反射机制概述.获取Class实例.类的加载与ClassLoader的理解.创建运行时类的对象.获取运行时类的完整结构.调用运行时类的指定结构.动态代理 反射 1 Java反射机制概述 1.1 Java ...

  3. C++ - RTTI(RunTime Type Information)运行时类型信息 详解

    RTTI, RunTime Type Information, 运行时类型信息, 是多态的主要组成部分,  通过运行时(runtime)确定使用的类型, 执行不同的函数,复用(reuse)接口. dy ...

  4. wxWidgets:运行时类型信息 (RTTI)

    wxWidgets:运行时类型信息 (RTTI) wxWidgets:运行时类型信息 (RTTI) 类信息 RTTI例子 wxWidgets:运行时类型信息 (RTTI) C++ 的一个缺点曾经是没有 ...

  5. C++-运行时类型信息,异常(day11)

    一.运行时类型信息 1.typeid运算符 头文件:#include<typeinfo> C++的标准头文件,都对应相应的类 //sizeof(类型/变量/表达式),返回内存大小 type ...

  6. [面试] C/C++ 语法(六)—— RTTI(运行时类型信息)

    RTTI(RunTime Type Information),顾名思义,对象运行时类型信息,以便在运行时进行类型识别. C++ 的对象识别可通过以下三个技术得以实现: (1)dynamic_cast ...

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

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

  8. 通过反射--操作运行时类中的指定的属性/方法

    操作运行时类中的指定的属性: 1.getDeclaredField(String fieldName):获取运行类中指定变量名的属性: 2.保证当前属性时可访问的 : 属性.setAccessible ...

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

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

最新文章

  1. Android技术经理+资深工程师+研发工程师-杭州
  2. The method setOnClickListener(View.OnClickListener) in the type View is not applicable
  3. 王者荣耀进不去服务器维护中,王者荣耀苹果版更新后进不去 王者荣耀iOS版服务器维护怎么办...
  4. 十个最适合 Web 和 APP 开发的 NodeJS 框架
  5. 7、Python文件操作工具 openpyxl 工具 2
  6. 悲观锁定时如何避免可怕的死锁-以及Java 8的一些用法!
  7. electronjs MySQL,javascript – 在Electron应用程序中使用sql.js.
  8. Flex 布局实例教程
  9. php+分针和时针重合,关于时针和分钟重合次数的计算
  10. 4. 根据UDP端口号抓IPsec协议默认的500/4500端口报文
  11. python基础之进程、线程、协程篇
  12. 计算机教室管理使用规则,多媒体教室使用管理细则
  13. 成人python培训_B2B优选:成人编程爱好者学习
  14. 0基础可以考CPDA数据分析师证书吗
  15. 音频音乐与计算机的交融pdf,电脑音乐的研和应用.pdf
  16. 对象存储oss挂载工具ossfs的使用
  17. 消费品与社区图腾:从 Coven 看女性向 PFP 市场
  18. QQ怎么样设置透明头像?2020最新方法!一个小工具快速搞定!
  19. eclips快捷键大全
  20. linux系统可以安装天正吗,Linux上安装Wine运行AutoCAD实例[多图]

热门文章

  1. 服务器草稿位置在c盘可以吗,在网易邮箱中,如何设置能实现把发出的邮件保存在硬盘文件夹中,以便事后可以查阅?...
  2. 主机mysql在哪里找_虚拟主机数据库在哪里
  3. 与MQTT的初定情缘
  4. unity通过WebAPI连接Websocket实现讯飞语音识别与合成。
  5. 唯在珠峰之巅,能欣赏到如许壮阔的5G时代
  6. 共享盘里文件excel提示文件已损坏无法打开的解决办法
  7. Java Lambda表达式的箭头理解总结
  8. 如何让生活变得更美好
  9. 学校与计算机教室安全责任书,学校办公室安全责任书
  10. 【报错记录】SpringBoot中MultipartFile上传报/tmp/tomcat.***.tmp (No such file or directory)