Analysis of MFC (4) Analysis of COBJECT

zhaozj2021-02-08  247

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.

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

New Post(0)