MFC RTTI learning notes

xiaoxiao2021-03-06  39

1. The core classes CRuntimeClass.struct CRuntimeClass {// Attributes LPCSTR m_lpszClassName; int m_nObjectSize; UINT m_wSchema; // schema number of the loaded class CObject * (PASCAL * m_pfnCreateObject) (); // NULL => abstract class CRuntimeClass * m_pBaseClass;

COBJECT * CREATEOBJECT (); static cruntimeclass * pascal loading ();

// CruntimeClass Objects Linked TOGETHER IN Simple List Static CruntimeClass * PfirstClass; // Start of class list cruntimeclass * m_pnextclass; // linked list of registered classes}

CruntimeClass key field:

1.1 m_lpszclassname: Type name, all categories that implement RTTI are created through this name. Named Specification is the _lpsz class name To create class cobject, the corresponding cruntimeclass class is ClassCObject, the ClassCoBject's m_lpszclassName field value is Szcobject.

1.2 m_pfncreateObject: Function pointer, its declaration is: cobject * (Pascal * m_pfncreateObject (); 1.3 CreateObject () function This is: cobject * createObject ();

1.4 PfirstClass and M_PNextClass It has declared as: static cruntimeclass * pfirstclass; // start of class listcruntimeclass * m_pnextclass;

Note: PfirstClass is stated as static, because this attribute is to be assigned at the beginning and m_pnextclass is non-static

CruntimeClass builds all supported type linked lists through these two properties.

------------------------- ------------------------ --------- If you want to create a class CA, you must inherit from COBject .2. Add a CRUNTIMECLASS type static member variable Classca in class CA (Variable Name must be based on naming Class class name): public : static cruntimeclass classca;

3. Add the pointer of the Classca member variable to the CRUNTIME class list (the elements in this class are inherited from cruntime). 4. Initializing static variables Classca: CruntimeClass Ca :: CA: Classca = {"_lpszca", sizeof (ca), 0xfff, ca :: createObject, // function pointer, Classca's M_PFNCREATEOBJECT member variable is specified as CA :: CreateObject. // NULL indicates that CA is a virtual class (& cobject :: classcObject), 0}; 5. Define a LOAD function in CRUntimeClass, which is the function of finding this class according to the parameter in the CRUNTIMECLASS class list, if present, return the class pointer CRuntimeClass * * CRuntimeClass :: Load (char szClassName) {CRuntimeClass * pClass; for (pClass = pFirstClass;! pClass = NULL; pClass = pClass-> m_pNextClass) {if (strcmp (szClassName, pClass-> m_lpszClassName) = = 0) RETURN PCLASS;} // Class Return NULL;} 6. Call the Load function and set the parameters to "Classca" cruntimeclass * pclassref; pclassref = cruntimeclass :: load (); // This example Get it is a static member variable Classca, a static member variable. Then call the classca's createObject () function cobject * pob; Pob = pclassref-> createObject (); POB-> DOSMETHING (); // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------- core macro: all types of strategies and definitions are achieved by macro. Unable to implement function, because all types must be determined when compiling. These macros can be divided into 2 categories:

1. Building a macro of type linked list in cruntimeclass

1.1 Declare_Dynamic (class_name):

#define declare_dynamic (class_name) / public: / static cruntimeclass class ## class_name; / virtual cruntimeclass * getRuntimeClass () const;

1.2 Implement_Dynamic (class_name, base_class_name)

#define import_dynamic (class_name, base_class_name) / _IMPLEMENT_RUNTIMECLASS (Class_name, Base_Class_name, 0xfff, Null)

2. Create a macro of the class name

2.1 Declare_Dyncreate (class_name)

#define declare_dyncreate (class_name) / declare_dynamic (class_name) / static cobject * pascal createObject ();

2.2 IMPLEMENT_DYNCREATE (class_name, base_class_name) #define IMPLEMENT_DYNCREATE (class_name, base_class_name) / CObject * PASCAL class_name :: CreateObject () / {return new class_name;} / _IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, 0xFFFF, / class_name :: CreateObject)

Note: The second type of macro (macro created by the type name) contains the corresponding first type of macro (Declare and Implement), so if you use the second type of macro, you don't need to use the first type of macro. That is, if you use a second type of macro to declare and implement the dynamic creation of the class, the creation of the dynamic class list is automatically completed.

However, if some dynamic classes cannot be created, only the first type of macro can be applied. For example, false (such as cobject (it is a lot of specific classes of the parent class), there is this class in the CRUNTIMECLASS class list, but can't create it because it does not use the second type of macro (ie there is no createObject function) .

3. Another important macro _IMPLEMENT_RUNTIMECLASS in IMPLEMENT_DYNAMIC IMPLEMENT_DYNCREATE macro and are called macro _IMPLEMENT_RUNTIMECLASS, but preferably for a parameter (represented createobject function pointer) using different parameter values ​​(). IMPLEMENT_DYNAMIC use NULL, IMPLEMENT_DYNCREATE The macro uses class_name :: createObject. Null indicates that there is no implementation of the CreateObject function, but also the corresponding class is a virtual class. _IMPLEMENT_RUNTIMECLASS macro definitions (very responsible, in fact, it is the real core macro): #define _IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, pfnNew) / static char _lpsz ## class_name [] = #class_name; / CRuntimeClass class_name :: class # #class_name = {/ _lpsz ## class_name, sizeof (class_name), wSchema, pfnNew, / RUNTIME_CLASS (base_class_name), NULL}; / static AFX_CLASSINIT _init _ ## class_name (& class_name :: class ## class_name); / CRuntimeClass * class_name: : GetRuntimeClass () const / {return & class_name :: class ## class_name;} /

It contains a static class AFX_CLASSINIT's instance object, which is stringing the type linked list by this object. Afx_classinit is under the declaration and definition of the following:

Struct AFX_CLASSINIT {AFX_ClassInit (CruntimeClass * PNewclass);

AFX_CLASSINIT :: AFX_CLASSINIT (CRuntimeClass * pNewClass) {pNewClass-> m_pNextClass = CRuntimeClass :: pFirstClass; CRuntimeClass :: pFirstClass = pNewClass;} // -------------------- -------------------------------- Key Summary: The function is through the basic all variables achieved by macro. Static, to define a good naming specification, which is the premise of the macro that correctly reaches a premise.

/ / -------------------------------------------------------------------------------------------- --------

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

New Post(0)