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; else acrx_abort(ACRX_T(/*MSGO*/"Class mismatch")); } } MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#MyClass)); } static void rxInit(AppNameChangeFuncPtr); #else static 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; else acrx_abort(ACRX_T(/*MSGO*/"Class mismatch")); } } MyClass::gpDesc = newAcRxClass(ACRX_T(#MyClass), ACRX_T(#PARENT_CLASS), VERNO, &make##MyClass); } #endif static 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
基础知识:
a 正常情况下,基类指针调用基类成员(成员变量和成员函数);派生类指针调用派生类成员
b 公有派生时基类指针允许指向派生类对象,但只能调用派生类继承自基类的成员而不能访问扩展部分成员
c 以私有派生时,基类指针不允许指向派生类对象
d 派生类指针不允许指向基类对象
另:基类的指针可以强制转换为派生类指针,反之不可。
静态成员函数只能对类内静态数据成员访问,也允许调用另一个静态成员函数,但不能访问其它成员。
公有的和保护的静态成员可以被继承,此时基类对象和派生对象共享静态成员。
AcRxClass是ARX所有类的基类
//desc() isKindOf() cast() isA()定义 static AcRxClass * desc(); inline bool isKindOf( const AcRxClass * aClass ) const; virtual AcRxClass * isA() const; static AcRxObject * cast( const AcRxObject * inPtr); //下面看如下代码 AcDbEntity *pEnt = NULL; AcDbObjectId ObjId = ObjId::kNull; acdbOpenObject(pEnt,ObjId,AcDb::kForRead,Adesk::kFalse); //判断是否为单行文本类型 if(pEnt->isKindOf(AcDbText::desc())) { AcDbText *pText=AcDbText::cast(pEnt);//pEnt这时指的已经是AcDbText类 }
上面代友中用到了 desc() isKindOf() cast() 三个函数:
pEnt 是AcDbEntity类型的指针,AcDbEntity是AcDbText的父类,在acdbOpenObject函数中,它指向了它的某一个子类,按基础知识判断,是允许的。
isA()函数无传入参数,返回不是bool型,^_^,虽然它的名字看起来有点象。其实它的功能和 desc()很像,只是它返回的值是 this所特指的类
//isA()的示例 AcDbEntity *pEnt = NULL; AcDbObjectId ObjId = ObjId::kNull; acdbOpenObject(pEnt,ObjId,AcDb::kForRead,Adesk::kFalse); //判断实体,如果不是SPLine类型则返回 if(pEnt->isA() != AcDbSpline::desc()) { pEnt->close(); return; }
https://blog.csdn.net/iMatt/article/details/85001405
https://blog.csdn.net/MM252685905/article/details/52650749
文章评论