COBJECT
FMD (http://www.fmdstudio.net)
Analysis of MFC COBJECT
1.COBJECT brief statement
2.cruntimeclass structure
3.Runtime_class
4. Dynamic support
5. DyncReate support
6.Serial support
COBJECT is the base class of most of the MFC classes
In order to complete the judgment of the MFC class, dynamic generation, serialization, etc., specific processing is added to the COBject.
In order to further enhance the understanding of the MFC class object, the COBJECT source code and related macro definition are analyzed.
(The attached code is not the original code, which is deleted for explanation.)
1.COBJECT brief statement
Class COBJECT
{
PUBLIC:
Virtual cruntimeclass * getruntimeclass () const;
Virtual ~ COBJECT ();
Void * Pascal Operator new (size_t nsize);
Void * Pascal Operator New (size_t, void * p);
Void Pascal Operator Delete (Void * P);
Void Pascal Operator Delete (Void * P, Void * PPLACE);
#if Defined // Debug mode, more nLINE parameters, used to save the original code line number.
Void * Pascal Operator New (size_t nsize, lpcstr lpszfilename, int nline);
Void Pascal Operator Delete (Void * P, LPCSTR LPSZFILENAME, INT NLINE);
#ENDIF
protected:
COBJECT ();
Private:
COBJECT (Const Cobject & Objectsrc);
Void Operator = (Const Cobject & ObjectSrc);
// attributes
PUBLIC:
Bool isserializable () const;
Bool iskindof (const cruntimeclass * pclass) const;
// Overridables
Virtual Void Serialize (CARCHIVE & A);
#if defined (_debug) // In debug mode
Virtual void assertvalid () const;
Virtual Void Dump (CDumpContext & DC) Const;
#ENDIF
PUBLIC:
Static const AFX_DATA CRUNTIMECLASS CLASSCOBJECT;
Static cruntimeclass * pascal _getbaseclass ();
}
Many of this statement are pure virtual functions, the "interface" of a general object defined.
2.cruntimeclass structure
Include a static member variable in COBject,
Static Cruntimeclass ClassCObject;
It is an important structure for the MFC to manage classes, which records important information from the class of many objects, which is managed by it at runtime. Many internal management member functions and macro definitions are based on CRUNTIMECLASS.
Struct cruntimeclass
{
// class name
LPCSTR M_LPSZCLASSNAME;
//size
INT m_nObjectsize;
//version
UINT M_WSCHEMA;
COBJECT * (Pascal * m_pfncreateObject) (); // null => Abstract Class
// Pointer to the base class CRUNTIMECLASS for inheritance relationships in the runtime record class. #ifdef _AFXDLL
Cruntimeclass * (Pascal * m_pfNgetBaseClass) ();
#ELSE
Cruntimeclass * m_pbaseclass;
#ENDIF
// Operations
// Establish an object
COBJECT * CREATEOBJECT ();
// derived judgment
Bool isderiveDFrom (const cruntimeclass * pbaseclass) const;
// Implementation
//storage
Void Store (CARCHIVE & AR) Const;
//Read
Static CruntimeClass * Pascal Load (CARCHIVE & Ar, Uint * Pwschemanum);
// CruntimeClass Objects Linked TOGETHER in Simple List
Cruntimeclass * m_pnextclass; // linked list of registered classes
}
3.Runtime_class
Runtime_class (class_name) is used to return a pointer to the runtime information structure
Defined as follows:
#define runtime_class (Class_name) (CRUNTIMECLASS *) (& class_name :: class ## class_name))
4. Dynamic support
In COBJECT derived class, you can get dynamic "verification" support, access runtime information
method:
Add Hong: Declare_Dynamic (class_name)
Adding a macro when implementing: import_dynamic
Original analysis:
Declare_dynamic (class_name) is equivalent to adding as follows in the class
protected:
Static cruntimeclass * pascal _getbaseclass ();
PUBLIC:
// Static member CruntimeClass, add runtime information to this derived class so that CRUNTIMECLASS members can be used to determine class information.
// This member name format is "Class" "class name", and the runtime_class () macro is a pointer to this structure.
Static const AFX_DATA CRUNTIMECLASS Class ## Class_name;
Virtual cruntimeclass * getruntimeclass () const;
Implement_dynamic:
#define import_dynamic (class_name, base_class_name) Implement_RuntimeClass (Class_name, Base_Class_name, 0xfff, NULL)
#define import_runtimeclass (class_name, base_class_name, wschema, pfnnew) 指 指 基 类 类 运 运 运 指 指 指 指
Cruntimeclass * pascal class_name :: _ getBaseClass () {return runtime_class (base_class_name);} // Initialize the runtime information of this class, in turn, the size, version, NULL, base class
AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name :: class ## class_name = {#class_name, sizeof (class class_name), wSchema, pfnNew, & class_name :: _ GetBaseClass, NULL}; // return runtime class information, override GetRuntimeClass CObject so a specific interface to the derived class CObject declared valid CRuntimeClass * class_name :: GetRuntimeClass () const {return RUNTIME_CLASS (class_name);} with this, you can use the RUNTIME_CLASS () macros, and with BOOL IsKindOf (const CRuntimeClass * pClass) Const judgment class type.
5. DyncReate support
Instances of class dynamics support
method:
Add declaration: Declare_Dyncreate (class_name)
Add Implementation: Implement_DyncReate (Class_name, Base_Class_Name)
Original analysis:
Declare_Dyncreate (class_name)
#define declare_dyncreate (class_name) // has Dynamic Support
Declare_dynamic (class_name) // Object establishes support
Static COBJECT * PASCAL CREATEOBJECT ();
Implement_dyncreate (class_name, base_class_name):
#define import_dyncreate (class_name, base_class_name) // Dynamically established an object
COBJECT * PASCAL class_name :: createObject () {return new class_name;} // Fill in runtime information, with Dynamic, there is a PFNNew parameter
Implement_runtimeclass (class_name, base_class_name, 0xffff, class_name :: createObject)
6.Serial support
Store objects, and read established object support
method:
Add declaration: Declare_serial (class_name)
Add implementation: import_serial (class_name, base_class_name, wschema)
Original analysis
Declare_serial (class_name):
#define declare_serial (class_name) // Dynamic Build Support
_Declare_dyncreate (class_name) // Document Operator
AFX_API Friend Carchive & AFXAPI Operator >> (CARCHIVE & AR, CLASS_NAME * & PO);
Implement_serial (class_name, base_class_name, wschema):
#define import_serial (class_name, base_class_name, wschema) // Dynamic Build Support
COBJECT * PASCAL class_name :: createObject () {return new class_name;} // Fill in the runtime class information, including the version number, generate function pointer
_IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, class_name :: CreateObject) AFX_CLASSINIT _init _ ## class_name (RUNTIME_CLASS (class_name)); // documentation in support of CArchive & AFXAPI operator >> (CArchive & ar, class_name * & pOb) {pOb = (class_name *) Ar.readObject (runtime_class (class_name)); Return Ar;} Rebursing Virtual Void Serialize (CARCHIVE & AR) in the derived class; to achieve preservation and establishment of class data. Thereby implementing the preservation of the class, and reading dynamic establishment.