Post a blog. A friend on the box thinks that class's construction and destructor delay loading. Is the construction of class that is called after the initialization of the unit. The destructor of the class that was called before the unit's inverse initialization.
To prove it, I did another experiment.
Unit Unit2;
Interface
Type
Tclasstest = Class
class constructor Create ();
Class destructor destory ();
End
Implementation
Uses
Windows;
{Tclasstest}
class constructor Tclasstest.create;
Begin
OutputDebugString (' class constructor ');
End
Class destructor tclasstest.destory;
Begin
OutputDebugString (' class destructor ');
End
Initialization
OutputDebugString (' Unit initialization ');
Finalization
OutputDebugString (' Unit finalization ');
End.
To prevent the compiler from being optimized for tclasstest not being used, tclasstest is removed. So we're going to use tclasstest.
Procedure Tform1.formcreate (Sender:tobject);
Begin
Caption: = Tclasstest.classname;
End
Run, and then exit. In the Event Log window we see.
The construction of the visible class is called before the unit is initialized, and the destructor of the class is called after the unit is reinitialized.
Debug Output:class Constructor Process Project1.exe (3940)
Debug Output:unit Initialization Process Project1.exe (3940)
Debug output:unit Finalization Process Project1.exe (3940)
Debug Output:class destructor Process Project1.exe (3940)
And then look at the case where there are derived classes, ancestor classes.
Unit Unit2;
Interface
Type
Tclasstestparent = Class
class constructor Create ();
Class destructor destory ();
End
Tclasstest = Class (Tclasstestparent)
class constructor Create ();
Class destructor destory ();
End
Implementation
Uses
Windows;
{Tclasstest}
class constructor Tclasstest.create;
Begin
OutputDebugString (' class constructor ');
End
Class destructor tclasstest.destory;
Begin
OutputDebugString (' class destructor ');
End
{Tclasstestparent}
class constructor Tclasstestparent.create;
Begin
OutputDebugString (' Parent class constructor ');
End
Class destructor tclasstestparent.destory;
Begin
OutputDebugString (' Parent class destructor ');
End
Initialization
OutputDebugString (' Unit initialization ');
Finalization
OutputDebugString (' Unit finalization ');
End.
So the result is:
Debug Output:parent class constructor Process Project1.exe (3256)
Debug Output:class Constructor Process Project1.exe (3256)
Debug Output:unit Initialization Process Project1.exe (3256)
Debug output:unit Finalization Process Project1.exe (3256)
Debug Output:class destructor Process Project1.exe (3256)
Debug Output:parent class destructor Process Project1.exe (3256)
It can be seen that if there is a class inheritance, the rule is
The structure of my father's class, then the construction of the subclass, and finally the unit initialization, the first unit inverse initialization, then the subclass destructor, and finally the parent class destructor.
And then further test:
Tclasstesta = Class
Public
class constructor Create ();
Class destructor destory ();
End
TCLASSTESTB = Class
class constructor Create ();
Class destructor destory ();
End
Discovering multiple unrelated classes within the same cell, it seems, is that the class constructor is the opposite of the declaration order. Destructors are the same as the declaration order
Further testing
Change the following code:
class constructor Tclasstestb.create;
Begin
if (Tclasstesta.classname = ") Then
Else
OutputDebugString (' Class B constructor ');
End
It is found that if another class is used in the construction of a class, the construction order is called first to invoke the construction of the referenced class.
This reminds me of an interesting question, and what would happen if the loop was used. My guess is that maybe the compiler won't let it pass.
class constructor Tclasstestb.create;
Begin
if (Tclasstesta.classname = ") Then
Else
OutputDebugString (' Class B constructor ');
End
class constructor Tclasstesta.create;
Begin
if (Tclasstestb.classname = ") Then
Else
OutputDebugString (' Class A constructor ');
End
Hey, I was surprised. The compiler passed. The result is that the class constructor loops through the other classes and becomes called the class constructor in declaration order, calling the class's destructor in reverse order of declaration order.
The final rule is:
1. The class destructor sequence is always the opposite of the class construction order, and the construction of the class is always called before the cell is initialized. The destructor of a class is always called after the cell is deserialized
2. Call the class construct in the reverse order of the Declaration without Association
3. The class constructor of the parent class is prioritized
4. Prioritize calling class constructs for other classes that are used in the class construction destructor
5. Call the class constructor in declared order if the class constructor is used in a loop
There may be other rules.
There is also an additional discovery. If the class has a constructor destructor, the code hints for the Delphi compiler will have a variable hint like tclasstesta. $ClassInitFlag.
The normal class does not have this hint. Of course, this thing must not be used in the code, because "$" is an illegal symbol in the name of the variable name function. It should be that some symbol table flags generated by the compiler were prompted. Oh.
http://blog.csdn.net/wr960204/article/details/4525763
Re-exploring the structure and the sequence of Delphi2010 class