Analysis of the top five key technologies of MFC (second part)

xiaoxiao2021-03-06  41

Analysis of the top five key technologies of MFC (second part)

Mr. Xiao Li

Second, runtime type identification (RTTI)

Runtime Type Identification (RTTI) is a program execution that a certain object is a class, and the RTTI that we usually contact with C is generally the RTTI of the compiler, ie, in the new version of the VC compiler, "make Energy RTTI, then load the typeInfo.h file, you can use a operator called TypeId (), its status is similar to the SizeOf () operator in C (containing a header file, then there is A familiar function). Typdid () critical places are acceptable to accept two types: one is a class name, one is an object pointer. So we discriminate whether an object belongs to a class, you can like it:

IF (classname) == typeid (* Objectname)) {

(Classname *) Objectname) -> fun ();

}

As mentioned above, a TypeId () operator can easily recognize whether an object belongs to a certain class, but the MFC is not a dynamic type identification with a TypeId () operator, but use a large stack. Macro with people with a man. Many students are very confused here, as if MFC is mysterious in most places. It is very fascinated when you have programmed it, just to join a group of macros here, add a map there, and don't know why we have to join these stuff.

In fact, early MFC did not have a TypeID () operator, so it can only be used along with an old way. We can even imagine that if the MFC has the concept of template (template), it may easily solve the RTTI problem.

So, we have to go back to "ancient" age, imagine what is going to do what RTTI wants to do. It's like we are in a new type (new to us, we don't know) the electrical company, we have to identify which is a rice cooker, which is an induction cooker, etc., we want to see a series of information of the registered electrical appliances, we can compare, Identify, what is the thing!

To register a series of news is not a simple thing, everyone may first think of the array registration object. But if you use an array, we have to define how much array is good, and it's a waste of space, and it's even more difficult. So we need to use another data structure - linked list. Because the linked list can be large, you can expand unlimited.

The linked list is a commonly used data structure, simply, which saves the pointer to the next homing object in an object. We can design our classes like this:

Struct cruntimeclass

{

...... The name of the name and other information ...

Cruntimeclass * m_pnextclass; // Pointer to the next CruntimeClass object in the linked list

}

The linked list should have a header and a tail, so that we know where to check when the information of each object element is checked. We have to indicate how you can derive it. So our linked list should be designed like this:

Struct cruntimeclass

{

...... The name of the name and other information ...

CruntimeClass * m_pbaseclass; // points to the base class to which the belongs.

CruntimeClass * m_pnextclass; // Defines the end of the end, you can define this pointer is empty.

Static cruntimeclass * pfirstclass; // Here the header pointer belongs to a static variable, because we know that the Static variable is only initialized once in memory, you can use it for each object! Guaranteed that there is only one header. }

With the CruntimeClass structure, we can define a list:

Static cruntimeclass classcobject = {null, null}; // defines a CRUNTIMECLASS object because the ClassCObject has no base class, so m_pbaseclass is NULL. Because there is currently only one element (ie there is no next element), m_pnextclass is NULL (end).

As for pfirstclass, everyone may have a bit unreasonable, where it goes to. Because we don't want to use ClassCobject as a linked list header, we have to insert a lot of CRUntimeclass objects, and because pfirstclass is the Static pointer, that is, it does not belong to an object, so we have initialized before using it: Cruntimeclass * cruntimeclass :: pfirstclass = NULL;

Now we can insert a CRUNTIMECLASS object in front. I have to declare it before inserting: If you are simply for runtime type identification, we don't have to use the m_pnextclass pointer (more is created at runtime), we care about the class itself. And its base class. In this way, when you find an object belong to a class, the main concern is the class itself and its base class.

Cruntimeclass classcmdtarget = {& classcObject, null};

Cruntimeclass classcwnd = {& classccmdtarget, null};

Cruntimeclass classcview = {& classcwnd, null};

Ok, it is just a pointer m_pbaseclass assignment (the real cruntimeclass in the MFC has multiple member variables and methods), and is connected to the list. Suppose we have now constructed all the CRUNTIMECLASS objects you need, then, you should define the header at this time. That is to point to the CRUNTIMECLASS object of our last constructed with the PFirstClass pointer - ClassCVIEW.

Cruntimeclass :: PfirstClass = & classcview;

Now, the list is perfect, the head is tail, and the problem has appeared, how should we access every CruntimeClass object? To determine an object belongs to a class, we have to start from the head, and always find the end tail, then can you compare the results? It is definitely not the case!

Everyone can think about it, we construct the purpose of this linked list, it is to be constructed, you can compare the elements in the CRUntimeClass object and the elements in the list, see if one of the objects you specify. This way, we need to have a function, a function that returns your own type name GetRuntimeClass ().

The process of simply talking about the chain list is simply, but this linked list is no meaning. Back to MFC, we have to implement a CRUNTIMECLASS object in each class that needs to have RTTI capabilities, and compares whether a class belongs to an object, it is actually just a CRUNTIMECLASS object. How to insert a CruntimeClass object in each class, and specify the contents of the CRUntimeClass object and the link to the CRUntimeClass object, you can do it here to complete it. In each class design that needs to have RTTI capabilities, it is a boring thing, it is easy to make mistakes, so MFC uses two macro replacement these work, named DECLARE_DYNAMIC (class name) and import_dynamic. Class name, base class name). From these two macros We can see that the CruntimeClass object constructive in the MFC name class is only the same name and the base class name!

At this point, there may be a friend asking: Why do you use two macros, can you use a macro to change the CRUNTIMECLASS object constructor? Personally think that it can be sure, because the macro is just a game that is converted. But we are in programming, the header files are separated from the source file, we have to declare the variables and methods in the header file header, and implement specific implementation in the source file. That is, we have to declare in the header file:

PUBLIC:

Static cruntimeclass classxxx // xxx is a class name

Virtual cruntime * getruntimeclass () const;

Then implement in the source file:

CruntimeClass * xxx :: classxxx = {...};

Cruntime * getruntimeclass () const;

{RETURN & XXX :: Classxxx;} // This cannot be returned to & Classxxx directly, because the static variable is class owned rather than object ownership.

Let's see the declare_dynamic (class name) macro in the MFC should be defined:

#define declare_dynamic (class_name) public: static cruntimeclass class ## class_name; Virtual cruntimeclass * getRuntimeClass () Const;

Where ## is the connecting man, let us introduce the class name plus Class, otherwise you will know what the result is generated.

After the above DECLARE_DYNAMIC (class name) macro, we write a sentence in the header file.

Declare_dynamic (xxx)

After the macro show, we want we want:

PUBLIC:

Static cruntimeclass classxxx // xxx is a class name

Virtual cruntime * getruntimeclass () const;

For the import_dynamic (class name, base class name), it seems that it is not worth it to change the text. Everyone knows that it is aware of the matter, the macro shows what we do for us, and there is no meaning!

With this chain, it is like a type of network that stores various types, we can easily RTTI. COBJECT has a function BOOL iskindof (const cruntimeclass * pclass) const; and is inherited by all the following factions below.

This function is implemented as follows:

Bool COBject :: Iskindof (const cruntimeclass * pclass) Const

{

Cruntimeclass * pclassthis = getRuntimeClass (); // Get your own CRUNTIMECLASS object pointer. While (pclassthis! = null)

{

IF (PCLASSTHIS == PCLASS) RETURN TRUE;

PCLASSTHIS = PCLASSTHIS-> M_PBASECLASS; // This is the most critical, pointing to your own base class, turn back, until the end of M_PBaseClass is NULL.

}

Return False;

}

Speaking here, runtime type identification (RTTI) is completed. When I wrote this article, I have been a cold. I once thought about what I wrote this thing. Because if I use these times in other places (even helping others to typing), there should be hundreds of yuan. What makes "财 财 如 如", I continue to write? I think, nothing more than wants to pay a few computers. The computer is a well-known high-tech thing, but most of the friends who study it can only silently, and friends don't know how to meet you. The programmer is not "trend" thing, and it is even more recognized by others. One person thinks is a typical thing, one day, I will follow a friend to a unit. There is a female typist in it. Friends looked at her skilled fingering, and said that her computer level is higher than you! " It is definitely better than you (finger)! Change it to you, if you have a living, I don't dare to say you! ". Although I want to declare that I am a computer professional, I know that I have not understood, so I have to politely. The choice of "trend" is actually chosen ordinary, and the choice to make programmers will choose loneliness! Fortunately, I am not a specialized programmer, but even so, I am willing to be your friend because I love you!

E-mail: Liyi268 QQ: 14653353

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

New Post(0)