Delphi's atomic world

zhaozj2021-02-16  83

During using the Delphi development software, we are like a group of happy cattle and sheep, carefree enjoy the Object Pascal language, and the rich water grass provided by the sunshine and various VCL controls. Looking up, you are looking at the sky, you can taste the dense grass on the earth, who will want to think how big is the universe, what is more than the molecule and the atom? That is a philosopher. At this time, the philosopher is sitting on the top of the high mountain, looking up at the universe nebula transform, staring at the hilarious crawling, looked back, nodding the cattle and sheep grazing. Smile. If you pull up a grass, you gently contain it in your mouth, close your eyes, try it, don't know what this green grass is in the mouth of philosophers? Just, his face has been with satisfactory smile. Understand and understand Delphi's micro-world world, which allows us to completely understand the macro application structure of Delphi, and develop our software in a broader ideological space. This is like, Newton discovers the movement of the macro object, but because of why it is unclear why this is moving like this, Einstein experiences the happy life of relativism between basic particle regular and macro object! What is the first section of TOBJECT atom TOBJECT? It is the basic core of the Object Pascal language architecture and the origin of various VCL controls. We can think that TOBJECT is one of the atoms constituting the Delphi application, of course, they are constituted by a thinner particles such as basic Pascal syntax elements. Saying Tobject is the atom of the Delphi program because Tobject is supported by the Delphi compiler. All objects are derived from TOBJECT, even if you do not specify TOBJECT for ancestors. TOBJECT is defined at the System unit, which is part of the system. At the beginning of the System.Pas unit, there is such an comment text: {PREDEFINED Constants, Types, Procedures,} {and functions (Such as true, integer, or} {WriteLn) do not have it actual declarations.} {Instead they isy INTO The Compiler} {AND area Treated as if They were declared} {at the beginning, this unit contains predefined constants, types, procedures, and functions (such as: ture, integer or Writeln), they don't actually declare, but the compiler is built into, and the beginning of the compilation is considered to be defined. You can join other source program files such as Classes.Pas or Windows.PAS to compile and debug their source code, but you must not add the System.PAS source file to your project file to compile! Delphi will report the report repeatedly define the System's compilation error! Therefore, TOBJECT is the definition provided inside the compiler. For those we use the Delphi development program, Tobject is atomic things.

TObject defined in the System unit is such that: TObject = class constructor Create; procedure Free; class function InitInstance (Instance: Pointer): TObject; procedure CleanupInstance; function ClassType: TClass; class function ClassName: ShortString; class function ClassNameIs (const name: string): Boolean; class function ClassParent: TClass; class function ClassInfo: Pointer; class function instanceSize: Longint; class function InheritsFrom (AClass: TClass): Boolean; class function MethodAddress (const name: ShortString): Pointer; class function MethodName (Address: Pointer): ShortString; function FieldAddress (const Name: ShortString): Pointer; function GetInterface (const IID: TGUID; out Obj): Boolean; class function GetInterfaceEntry (const IID: TGUID): PInterfaceEntry; class function GetInterfaceTable: PInterfaceTable; function SafeCallException (ExceptObject: TObject; ExceptAddr: Pointer): HResult; virtual; procedure AfterConstruction; virtual; procedure BeforeDestruction; virtual; procedure Dispatch (var Message); virtual; proce dure DefaultHandler (var Message); virtual; class function NewInstance: TObject; virtual; procedure FreeInstance; virtual; destructor Destroy; virtual; end; Here, we will gradually knocking on the door TObject atoms, which in the end is to see what the structure. We know, TOBJECT is the basic class of all objects, then what is an object? Any object in Delphi is a pointer, which refers to a space occupied by the object in memory! Although the object is a pointer, we don't have to write like this code myObject ^ .GetName when we reference the object of the object, but can only be written as MyObject.getname, which is supported by the compiler. Friends using C Builder know the relationship between objects and pointers, because the objects of C Builder are defined as pointers. The object pointer points to the object space for the object stores data, and we analyze the data structure of the memory space points to the object pointer. The head 4 bytes of the object space is the virtual method address table (VMT - Vritual Method Table).

The next space is a space that stores the member data of the object itself, and is stored in the order of the data member of the object class from the data member of the object class, and the definition order of the data member in each class. The false method of the class (VMT) saves the process address of the original ancestor derived from the original ancestors of this class to all classes of the class. The virtual method of the class is to use the method of reserving the word Vritual declaration, the virtual method is the basic mechanism for achieving the object polymorphism. Although the dynamic method of reserving the word Dynamic declaration can also realize the polymorphism of the object, but such a method is not saved in the virtual method address table (VMT), it is only another kind of storage space provided by Object Pascal. Polymorphism implementation mechanism, but it is at the expense of call speed. Even if we do not define any class of false methods, the objects of such a class still exist pointers to the virtual method address table, just that the address item is zero. However, those false methods, such as DESTROY, FreeInstance, etc. in TOBJECT, and where is it stored? It turns out that their method address is stored in a space offset in the negative direction of the VMT pointer. In fact, the data space in the negative direction of the VMT table offsets 76 bytes is the system data structure of the object class, which is related to the compiler and may be changed in the future Delphi version. Therefore, you can think that VMT is a data structure starting from the negative offset address space, the negative offset data area is the system data area of ​​the VMT, and the positive offset data of the VMT is the user data area (custom imaginary address table. ). The functions and processes of class information or object runtime information defined in TOBJECT are generally related to system data of VMT. A VMT data represents a class, in fact, VMT is class! In Object Pascal, we use TOBJECT, TCOMPONENT, and the like, which are implemented as their respective VMT data internally in Delphi. The type of class defined by Class of reserves the word definition is actually pointing to the pointer to the associated VMT data. For our app, VMT data is static data. After the compiler compiles to complete our application, these data information has been identified and initialized. The program statement we wrote can access the VMT related information, obtain information such as the size of the object, class name, or run time, or call the name and address of the virtual method or reading method. When an object is generated, the system assigns a memory space for the object and linked the object with the related class, so that the head 4 bytes in the data space allocated for the object, becomes a point VMT data. Pointer. Let's take a look at how the object is born and destroyed. Looking at my three-year-old son is active on the grass, it is because of the birth process of my life, I can really realize the meaning and greatness of life. Only those who have experienced death will be more understanding and cherish life. So let us understand the process of the production and demise of the object! We all know that using the following statement can construct a simple object: anObject: = TOBJECT.CREATE; the compiler implements its compilation as: based on the VMT corresponding to TOBJECT, call the TOBJECT CREATE constructor. In the CREATE constructor, the system's classcreate process is called, and the system's classcreate process is called the NewInstance virtual method in the class VMT. The purpose of calling the NewInstance method is to establish an instance space of the object, because we do not overload the method, so it is the newInstance of the Tobject class.

The NewInstance method of the TOBJEC class will call the getMem process to assign memory for the object based on the object instance size (InstanceSize) initialized in the VMT table, and then call the INITINSTANCE method to initialize the assigned space. The InitInstance method first initializes the heads of the object space to point to the pointer to the object class corresponding to the VMT, and then clear the remaining space. After establishing an object instance, a virtual methodAfterconstruction is called. Finally, save the address pointer of the object instance data into the anobject variable, so that anobject object is born. Similarly, use the following statement to eliminate an object: anObject.destroy; TOBJECT's destructor DESTROY is declared as a false method, and it is also one of the intrinsic methods of the system. The Destory method first calls the BeforeDestruction virtual method, then call the system's ClassDestroy process. The ClassDestory process calls the FreeInstance virtual method by class VMT, and the FreeInstance method is called the FreeMem process to release the memory space of the object. In this way, an object disappears in the system. The sect of the object is simpler than the structure of the object, as if the birth of life is a long birth process, and death is relatively short, which seems to be an inevitable law. During the structure and destructuring of the object, NEWINSTANCE and FreeInstance are invoked to create and release the memory space of the object instance. The reason why these two functions declare as virtual functions, in order to allow users to prepare a special object class that requires users to manage memory (such as in some special industrial control programs), there is extended space. The Afterconstruction and BeForedStruction declared as virtual functions, but also to the future class after the object, have the opportunity to breathe the newly born object breathe the first fresh air, and the object can allow the object to complete the good event before the object is done, this is Reasonable things. In fact, the TFORM object and the TDATAMODULE object's oncreate events and ONDESTROY events are triggered by these two virtual functions overloaded in TForm and TDATAMODULE. In addition, TOBJEC also provides a Free method, it is not a virtual method, which is specially provided for those who can freely release the object if it is empty (NIL). In fact, I can't figure out if the object is empty, it is a problem that the program logic is unclear. However, anyone is not perfect, it may make mistakes, using free to avoid accidental mistakes. However, writing the correct program cannot relisten to such a solution, or should be the first goal of the program's logical correctness! Interested friends can read the original code of the SYSTEM unit, where a large number of code is written in assembly language. Careful friends can find that the Tobject's constructor crete and destructor Destory did not write any code. In fact, in the debug state through the debug's CPU window, it clearly reflects the assembly code of Create and Destory. Because, Master Gate creating Delphi does not want to provide excessive complex things to users, they want users to write applications in simple concepts, hide complex work to the internal inside of the system by them. So, take the code of these two functions when publishing System.PAS units, allowing users to think that TOBJECT is the source of everything, the user derived class is completely from virtual, which is not wrong.

Although these most essential code reading Delphi requires a small amount of assembly language knowledge, but read this code, let us know the basic laws of the origins and development of the Delphi world. Even if you don't understand, you can at least understand some basic things, and write a Delphi program for us. The second section of the TCLASS atom is defined in the System.Pas unit: Tclass = Class of Tobject; It means that tclass is the class of TOBJECT. Because Tobject itself is a class, TCLASS is the class of the so-called class. Conceptually, TCLASS is the type of class, namely, class. However, we know a class of Delphi representing a VMT data. Therefore, the class can be considered to be the type defined for the VMT data item, in fact, it is a pointer type pointing to VMT data! In previous conventional C languages, it is not possible to define types of classes. Once the object is compiled, the structure information of the class has been converted to an absolute machine code, and there will be no complete class information in the memory. Some higher-level object-oriented languages ​​support dynamic access and calls for class information, but often require a complex internal interpretation mechanism and more system resources. The Delphi's Object Pascal language absorbs some of the excellent features of the high-level object-oriented language, and retains the traditional advantages that can be directly compiled into machine code, which relatively solves the problem of advanced features and program efficiency. It is because Delphi retains complete class information in the application, in order to provide advanced object-oriented functions such as AS and IS or the runtime conversion and discriminating classes, and the VMT data of the class plays a key core role. Interested friends can read the ASCLASS and ISClass two assembly processes of the System cell, they are the implementation code of the AS and IS operators to deepen the understanding of the class and VMT data. With the type of class, you can use the class as a variable. You can understand the variables of the class as a special object, you can access the class variables as access objects. For example: Let's look at the following program fragment: type TSampleClass = class of TSampleObject; TSampleObject = class (TObject) public constructor Create; destructor Destroy; override; class function GetSampleObjectCount: Integer; procedure GetObjectIndex: Integer; end; var aSampleClass: TSampleClass ACLASS: TCLASS; In this code, we define a class TsampleObject and its related class type TsampleClass, as well as two type variables asampleclass and aclass. In addition, we also define constructor, destructory functions, a class method GetSampleObjectCount, and an object method getObjectIndex. First, let's understand the meaning of class variables asampleclass and aclass. Obviously, you can use TSAMPLEOBJECT and TOBJECT as a constant value and assign them to the ACLASS variable, as if the 123 constant value is assigned to the integer variable I. Therefore, the relationship between class types, classes, and class variables is the relationship between type, constant, and variables, but is just about this level of the class rather than the object level.

Of course, directly assigning TOBJECT to AsampleClass, because asampleclass is the class variable of Tobject derived class TsampleObject, and TOBJECT does not include all definitions compatible with TsampleClass type. Instead, the TSAMPLEOBJECT assigns to the ACLASS variable is legal, because TsampleObject is the TOBJECT derived class, is compatible with the Tclass type. This is completely similar to the assignment and type matching of object variables. Then, let's take a look at what is a class method. The so-called method is to refer to the method called at the level of the class, as the getSampleObjectCount method as defined above, is a method of declaring the word Class Class. The class method is different from the object method that is called on the object level, and the object method has been familiar with us, and the class method is always used in the hierarchical use of all kinds of objects of all kinds of objects and centralized management objects. In the TOBJECT definition, we can find a large number of ways, such as ClassName, ClassInfo, and NewInstance, and more. Where newInstance is also defined as Virtual, ie empty class methods. This means that you can rewrite the NewInstance implementation method in derived subclasses to construct the object instance of this class in a special manner. You can also use the Self this identifier in the class method, but the meaning of its representative is different from the SELF in the object method. SELF in the class method indicates its own class, that is, pointing to the pointer of the VMT, and the SELF in the object method represents the object itself, that is, a pointer to the object data space. Although, the class method can only be used at the class level, but you can still call the class method through an object. For example, the class method className Class TOBJECT can be called by statement aobject.classname, because the heads of the object data space points to the object pointer are pointers to the class VMT. Instead, you can't call the object method at the class level, and the statement of TOBJECT.FREE must be illegal. It is worth noting that the constructor is a class method, and the destructor is an object method! what? The constructor is a class method, the destructor is an object method! Have you made a mistake? Look, when you create an object, use the statement similar to the following statement: AObject: = TOBJECT.CREATE; it is clearly a CREATE method called class TOBJECT. The following statement is used when deleting objects: AObject.destroy; even if the object is used to release the object, it is also a DESTROY method of the object. The reason is very simple, before constructing the object, the object does not exist, only class, creating objects can only be used. Instead, the delete object must be deleted an existing object, which is an object being released, not a class being released. Finally, the problem of the virtual construct function is discussed by the way. In the traditional C language, the false preframe function can be implemented, but the fictional creation function is a problem. Because, in a traditional C language, there is no type of type. The instance of the global object is in the global data space, and the local object of the function is also compiled, and the instance of the mapping in the stack space is compiled. Even the object created, but use the New operator to press the fixed class structure. The instance allocated in the heap space, and the constructor is just a method of initializing the generated object instance.

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

New Post(0)