ObjectARX运行时类信息实现原理
新公司维护基于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运行时类信息实现原理相关推荐
- 【MFC学习】运行时类信息机制
作用 在程序运行过程中可以获知对象的类的相关信息:机器知道 运行时类信息机制使用 类必须派生自CObject 类内必须添加声明宏 DECLARE_DYNAMIC(theClass) 类外必须添加实现宏 ...
- 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理
反射机制概述.获取Class实例.类的加载与ClassLoader的理解.创建运行时类的对象.获取运行时类的完整结构.调用运行时类的指定结构.动态代理 反射 1 Java反射机制概述 1.1 Java ...
- C++ - RTTI(RunTime Type Information)运行时类型信息 详解
RTTI, RunTime Type Information, 运行时类型信息, 是多态的主要组成部分, 通过运行时(runtime)确定使用的类型, 执行不同的函数,复用(reuse)接口. dy ...
- wxWidgets:运行时类型信息 (RTTI)
wxWidgets:运行时类型信息 (RTTI) wxWidgets:运行时类型信息 (RTTI) 类信息 RTTI例子 wxWidgets:运行时类型信息 (RTTI) C++ 的一个缺点曾经是没有 ...
- C++-运行时类型信息,异常(day11)
一.运行时类型信息 1.typeid运算符 头文件:#include<typeinfo> C++的标准头文件,都对应相应的类 //sizeof(类型/变量/表达式),返回内存大小 type ...
- [面试] C/C++ 语法(六)—— RTTI(运行时类型信息)
RTTI(RunTime Type Information),顾名思义,对象运行时类型信息,以便在运行时进行类型识别. C++ 的对象识别可通过以下三个技术得以实现: (1)dynamic_cast ...
- 在Amazon FreeRTOS V10中使用运行时统计信息
在MCU on Eclipse网站上看到Erich Styger在8月2日发的博文,一篇关于在Amazon FreeRTOS V10中使用运行时统计信息的文章,本人觉得很有启发,特将其翻译过来以备参考 ...
- 通过反射--操作运行时类中的指定的属性/方法
操作运行时类中的指定的属性: 1.getDeclaredField(String fieldName):获取运行类中指定变量名的属性: 2.保证当前属性时可访问的 : 属性.setAccessible ...
- java获取运行时对象,java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构...
我们可以通过反射,获取对应的运行时类中所有的属性.方法.构造器.父类.接口.父类的泛型.包.注解.异常等.... 典型代码: @Test public void test1(){ Class claz ...
最新文章
- Android技术经理+资深工程师+研发工程师-杭州
- The method setOnClickListener(View.OnClickListener) in the type View is not applicable
- 王者荣耀进不去服务器维护中,王者荣耀苹果版更新后进不去 王者荣耀iOS版服务器维护怎么办...
- 十个最适合 Web 和 APP 开发的 NodeJS 框架
- 7、Python文件操作工具 openpyxl 工具 2
- 悲观锁定时如何避免可怕的死锁-以及Java 8的一些用法!
- electronjs MySQL,javascript – 在Electron应用程序中使用sql.js.
- Flex 布局实例教程
- php+分针和时针重合,关于时针和分钟重合次数的计算
- 4. 根据UDP端口号抓IPsec协议默认的500/4500端口报文
- python基础之进程、线程、协程篇
- 计算机教室管理使用规则,多媒体教室使用管理细则
- 成人python培训_B2B优选:成人编程爱好者学习
- 0基础可以考CPDA数据分析师证书吗
- 音频音乐与计算机的交融pdf,电脑音乐的研和应用.pdf
- 对象存储oss挂载工具ossfs的使用
- 消费品与社区图腾:从 Coven 看女性向 PFP 市场
- QQ怎么样设置透明头像?2020最新方法!一个小工具快速搞定!
- eclips快捷键大全
- linux系统可以安装天正吗,Linux上安装Wine运行AutoCAD实例[多图]
热门文章
- 服务器草稿位置在c盘可以吗,在网易邮箱中,如何设置能实现把发出的邮件保存在硬盘文件夹中,以便事后可以查阅?...
- 主机mysql在哪里找_虚拟主机数据库在哪里
- 与MQTT的初定情缘
- unity通过WebAPI连接Websocket实现讯飞语音识别与合成。
- 唯在珠峰之巅,能欣赏到如许壮阔的5G时代
- 共享盘里文件excel提示文件已损坏无法打开的解决办法
- Java Lambda表达式的箭头理解总结
- 如何让生活变得更美好
- 学校与计算机教室安全责任书,学校办公室安全责任书
- 【报错记录】SpringBoot中MultipartFile上传报/tmp/tomcat.***.tmp (No such file or directory)