Learn from COBJECT and CRUNTIMECLASS

zhaozj2021-02-08  265

Author: Lin water raging shuinu@163.net reproduced leave authorship MFC CObject and CRuntimeClass are two very important classes / structures, most of the classes are based on MFC CObject as the base class, CRuntimeClass structure with inseparable CObject Understanding them is of great significance for in-depth understanding of MFC. First, the CruntimeClass structure is to understand COBJECT, let's take a look at the cruntimeclass is a configuration in the MFC. Each class derived from the COBject has a CRUNTIMECLASS object with it to complete the information of the class instance at runtime or its base class. In Afx.h, its definition is as follows: struct cruntimeclass {// attributeslpcstr m_lpszclassname; // class name, generally referring to the name INT m_nobjectsize of the class containing the CRUNTIMECLASS object; // contains the size of the CRUNTIMECLASS object, does not include it UINT m_wSchema memory allocation; // schema number of the loaded classCObject * (PASCAL * m_pfnCreateObject) (); // NULL => abstract class constructor to establish a point #ifdef example _AFXDLLCRuntimeClass * (PASCAL * m_pfnGetBaseClass) (); # ElseCruntimeClass * m_pbaseclass; # Endif // The pointer (function) of M_PBaseClass above is the key to the MFC runtime, which is a simple one-way linked list // OperationsCObject * createObject (); // This function gives COBJECT Delivery class Dynamically established capacity BOOL ISDERIVEDFROM (Const CRUNTIMECLASS * PBASECLASS) const; // This function uses m_pbaseclass or m_pfNgetBaseClass to traverse the entire class level to determine if PBaseClass points to the class, // Use it to determine if a class is pointing from PBASECLASS The class is derived. // Implementationvoid Store (CArchive & ar) const; static CRuntimeClass * PASCAL Load (CArchive & ar, UINT * pwSchemaNum); // CRuntimeClass objects linked together in simple listCRuntimeClass * m_pNextClass; // linked list of registered classes}; two, class CObject CObject It is the base class of most class of the MFC class, mainly through it: (1), run class information; (2), serialization; (3), object diagnostic output; (4), compatible with the collection class; (1), runtime information: Note: To get runtime information using the CRUNTIMECLASS structure, you must include Declare_Dynamic / Implement_Dynamic, Declare_DyncReate / Implement_DyncReate or Decrare_Serial / Implement_serial.

But your class must be derived from cobject to use these macros, because the following functions will be defined by declare_dynamic: cruntimeclass * pascal b :: _ getBaseClass () {return runtime_class (base_name);} where runtime_class is defined #define ruventime_class (class_name) / (CRUNTIMECLASS *) (& class_name :: class ## class_name); get the CRUNTIMECLASS object pointer in the class, which is obvious, if there is no base class, you will get a compilation error when you use Implement_Dynamic. Unless you don't have Declare_Dynamic as you like COBJECT, these functions are implemented, and getBaseClass in COBject is simply returned NULL. The actual afx.h DECLARE_DYNAMIC in the following statement: #define DECLARE_DYNAMIC (class_name) / protected: / static CRuntimeClass * PASCAL _GetBaseClass (); / public: / static const AFX_DATA CRuntimeClass class ## class_name; / virtual CRuntimeClass * GetRuntimeClass () const ; / IMPLEMENT_DYNAMIC in afx.h are defined as follows: #define IMPLEMENT_DYNAMIC (class_name, base_class_name) / IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, 0xFFFF, NULL) #define IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, pfnNew) / CRuntimeClass * PASCAL class_name :: _ GetBaseClass () / {return RUNTIME_CLASS (base_class_name);} / AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name :: class ## class_name = {/ # class_name, sizeof (class class_name), wSchema, pfnNew, / & class_name :: _ GetBaseClass, NULL}; / CRuntimeClass * Class_name :: getRuntimeClass () const / {return russime_class (class_name);} / where cruntimeclass * getRuntimeClass () const; is defined as a virtual function to complete overload at class level. This is also a way MFC utilizes a polymorphic implementation of dynamic information. The other two Declare_DyncReate and Declare_serial are similar. Only, they define and implement some functions. For the use of declare_dyncreate, it is necessary to have a class that must have a parameterless default constructor because a CreateObject function is defined in Declare_DyncReate used to build an object in a dynamic, it is just A simple return new class_name. Let's first look at the serialization: COBJECT implementation These features are implemented through the CruntimeClass object ClassObject in it, and CObject does not support multiple inheritance, that is, only one COBJECT base in the class level of COBJECT. class.

This is the relationship between the CruntimeClass object's member M_PBASECLASS. Because it is just a single-link list.

The following definition is that it is afx.h: /// class CObject is the root of all compliant objects # ifdef _AFXDLLclass CObject # elseclass AFX_NOVTABLE CObject # endif {public: // Object model (types, destruction, allocation) virtual CRuntimeClass * GetRuntimeClass () const; // achieve the above function only simple return RUNTIME_CLASS (classObject); virtual ~ CObject (); // virtual destructors are necessary // Diagnostic allocationsvoid * PASCAL operator new (size_t nSize); void * PASCAL Operator new (size_t, void * p); void pascal operator delete (void _msc_ver> = 1200void pASCAL Operator Delete (Void * p, void * pplace); # endif # if defined (_debug) &&! defined (_AFX_NO_DEBUG_CRT) // for file name / line number tracking using DEBUG_NEWvoid * PASCAL operator new (size_t nSize, LPCSTR lpszFileName, int nLine); # if _MSC_VER> = 1200void PASCAL operator delete (void * p, LPCSTR lpszFileName, int nLine); # e le d 店assign objects.protected: CObject (); private: CObject (const CObject & objectSrc); // no implementationvoid operator = (const CObject & objectSrc); // no implementation // Attributespublic: BOOL IsSerializable () const; // serialize objects of BOOL IsKindOf (const CRuntimeClass * pClass) const; // judge whether // Overridablesvirtual void Serialize (CArchive & ar); # if defined (_DEBUG) || defined (_AFXDLL) // Diagnostic Supportvirtual void AssertValid () const; virtual void dump (CDumpContext & dc) const; # endif // Implementationpublic: static const AFX_DATA CRuntimeClass classCObject; #ifdef _AFXDLLstatic CRuntimeClass * PASCAL _GetBaseClass (); # endif}; If you use your class definitions implemented and the optional macro wherein One, you have to know the benefits of derived from COBJECT.

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

New Post(0)