The foundation of the MFC class library-CObject

zhaozj2021-02-17  67

COBJECT is most of the MFC class base classes to complete special functions such as MFC classes, dynamic generation, serialization, etc., add specific processing. 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 deduced for the description of the problem.) Mainly introduced the following aspects: one .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, "interface" of a general object defined

Two .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

}

Three. 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))

Four. 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:

protected:

Static cruntimeclass * pascal _getbaseclass ();

PUBLIC:

// Static member CRUNTIMECLASS, add runtime information to this derived class,

// This allows you to use the CRUNTIMECLASS member to determine the 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; import_dynamic:

#define import_dynamic (class_name, base_class_name) /

Implement_runtimeclass (class_name, base_class_name, 0xfffff, null)

#define import_runtimeclass (class_name, base_class_name, wschema, pfnnew) /

/ / Return to the pointer to the base class runtime information structure

Cruntimeclass * pascal class_name :: _ getBaseClass () /

{RETURN Runtime_class (base_class_name);} /

// Initialize this class's runtime information, in turn, for class name, size, version, null, base class

AFX_COMDAT constimeclass class_name :: class ## Class_name = {/

#class_name, sizeof (class class_name), WSChema, PFNNEW, /

& class_name :: _ getBaseClass, Null}; /

// Return the runtime class information, overload the COBJECT GETRUNTIMECLASS, so that the interface declared in COBJECT is valid for the specific derived class

Cruntimeclass * class_name :: getRuntimeClass () const / {return runtime_class (class_name);} /

With this, you can use the runtime_class () macro, and use the 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 establishment support

Static COBJECT * PASCAL CREATEOBJECT ();

Implement_dyncreate (class_name, base_class_name):

#define import_dyncreate (class_name, base_class_name) /

/ / Dynamically establish an object

COBJECT * PASCAL CLASS_NAME :: CreateObject () /

{RETURN New Class_name;} /

// Fill in the runtime information, different from Dynamic, there is a PFNNEW parameter

Implement_runtimeclass (class_name, base_class_name, 0xffff, /

Class_name :: CreateObject)

Six.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 generation 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 generation support

COBJECT * PASCAL CLASS_NAME :: CreateObject () /

{RETURN New Class_name;} /

/ / Fill in the runtime 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)); /

// Document support implementation

CARCHIVE & AFXAPI Operator >> (CARCHIVE & AR, CLASS_NAME * & POB) /

{POB = (Class_name *) ar.readObject (runtime_class (class_name)); / return ar;} /

Rebate Virtual Void Serialize (CARCHIVE & AR) in the derived class; after reading the save and establishment of class data. Thereby implementing the preservation of the class, and reading dynamic establishment.

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

New Post(0)