About RTTI in MFC

xiaoxiao2021-03-06  18

Regarding RTTI in the MFC In the MFC, RTTI is to establish a linked list that records its type of type, and the CruntimeclassName; LPCSTR m_lpszclassName; // is used to record class names CruntimeClass * m_pbaseclass; // Used to point to the cruntimeclass structure of the base class CruntiMeclass * m_pnextclass; // is used to point to the previous class of the previous class const AFX_CLASSINIT * m_pclassinit; // Used to create a category record in this category record There are many routes, each of which can be found along M_PBaseClass, which can always find a final base class. A class should be added to the catalog of this category to use two Macro: DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC #define DECLARE_DYNAMIC (class_name) / public: / static const CRuntimeClass class ## class_name; / virtual CRuntimeClass * GetRuntimeClass () const; / this Macro is used in the class declaration, its role is based on the name of the class to add two public members, which are used to record the type of the class and the address of the object class ## class_name, pay attention to the class ## Class_name is a static member, which lays a foundation for the latter. After using Declare_Dynamic in the class, it is also necessary to use the import_dynamic macro in .cpp, the macro's role is to initialize the Class ## Class_name object and define the getRuntimeClass function. #define IMPLEMENT_DYNAMIC (class_name, base_class_name) / IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, 0xFFFF, NULL, NULL) IMPLEMENT_DYNAMIC when in use, to specify the class and its base class name, then use IMPLEMENT_RUNTIMECLASS substantive initialization activity.

#define IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, pfnNew, class_init) / AFX_COMDAT const CRuntimeClass class_name :: class ## class_name = {/ #class_name, sizeof (class class_name), wSchema, pfnNew, / RUNTIME_CLASS (base_class_name), NULL, class_init }; / CRuntimeClass * class_name :: GetRuntimeClass () const / {return RUNTIME_CLASS (class_name);} / wherein, in the initialization class # class_name and related RTTI only: & name_class used to initialize m_lpszClassNameRUNTIME_CLASS (base_class_name) is used to initialize CRuntimeClass * m_pBaseClassNULL used to initialize CRuntimeClass * m_pNextClass (At this category catalog has not been established) in addition, RUNTIME_CLASS is used to obtain a class ## class_name object address macro: #define RUNTIME_CLASS (class_name) _RUNTIME_CLASS (class_name) #define _RUNTIME_CLASS (class_name) / ((CRUNTIMECLASS *) (Class_name :: Class ## Class_Name) This, after each class in the program uses the declare_dynamic / usnamic macro, the class is registered in the category record. Of course, all classes in the MFC are derived from COBJECT, so all the routes must eventually meet in the COBject, because the cobject does not have the base class, so its cruntimeClass object does not implement the above two macro, in Objcore.cpp In the case of ClassCobject objects for COBJECT, the work is initialized:

Const struct cruntimeclass cobject :: classcObject = {"cobject", sizeof (cobject), 0xfff, null, null, null}; we can see that M_PBaseClass is initialized to NULL. In addition, GetRuntimeClass (): cruntimeclass * cobject :: getrimeclass () Const {Return_Runtime_class (cobject);} As for _Runtime_Class, it has already said. Thus in order to implement the RTTI of the object, we have done all the preparations. Let's take a look at its implementation, it is mainly done by the iskindof function in COBject. BOOL CObject :: IsKindOf (const CRuntimeClass * pClass) const {// the sake of simplicity, omitted unrelated code CRuntimeClass * pClassThis = GetRuntimeClass (); return pClassThis-> IsDerivedFrom (pClass);} Here, since the virtual function is GetRuntimeClass , PCLASSTHIS will point to the class ## class_name of the class object that calls the iskindof function, then use the pointer to the object to call isderivedFrom: BOOL CRUNTIMECLASS :: isderivedfrom (const cruntimeclass * pbaseclass) const {// For the sake of simple, slightly irrelevant code if (pBaseClass == NULL) return FALSE; // simple SI case const CRuntimeClass * pClassThis = this; while (! pClassThis = NULL) {if (pClassThis == pBaseClass) return TRUE; pClassThis = pClassThis-> m_pBaseClass;} Return False; // Walked to the top, no match} We know that the STATIC objects that are derived, class and base classes share the base class, so here, the derived class and the base class must share the same class ## Class_name object, this is We judge whether the two classes have inheritance relationships provide the theoretical foundation, and like, in IsDeriveDFROM, the IF in the While loop is indeed doing so, it takes along the same as the same route, as long as the common ancestor COBJECT, I will never give it.

转载请注明原文地址:https://www.9cbs.com/read-51032.html

New Post(0)