À propos de l'allocation et du recyclage de la mémoire des objets
Je ne sais pas si quelqu'un a des idées sur la façon de placer le registre dl ici. Sinon, réfléchissez-y. Si vous y réfléchissez, tout ira bien. En fait, avant le code suivant (1), il y a une telle ligne de code MOV dl, 1, alors pourquoi est-ce comme ça La raison n'est pas très simple, la réutilisation du code ? Concernant l'utilisation du registre dl ici, il y a une introduction dans l'aide de Delphi. Soyez patient et cherchez-le vous-même. Si vous le trouvez, vous serez un maître. C'est apprendre, non, apprendre à pêcher, pas demander du poisson. Borland a dit ceci : "J'utilise le registre dl pour stocker un indicateur. Si la valeur est 1, alors je créerai l'objet. Sinon, je ne créerai pas l'objet. Si vous êtes un peu flou, réfléchissez-y à nouveau et." encore. Si vous n'avez pas encore ouvert les yeux, alors jetez un oeil au code suivant (2), ne dites pas que vous ne l'avez pas trouvé, toussez, qu'est-ce qui se passe, je continue de dire des bêtises, je promets de ne pas le dire encore.
{Code (1)
tester dl, dl
jz +08$
ajouter des esp, -10$
appelez @ClassCreate }
{///Code (2)
PRocédure Tapplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance : TComponent ;
commencer
//////// Instance := TComponent(InstanceClass.NewInstance);
TComponent(Référence) := Instance ;
essayer
//////// Instance.Create(Self);
sauf
TComponent(Référence) := nul;
augmenter;
fin;
si (FMainForm = nil) et (L'instance est TForm) alors
commencer
TForm(Instance).HandleNeeded;
FMainForm := TForm(Instance);
fin;
fin;
}
Dans ce cas, c'est-à-dire que Delphi appelle le code (1) lorsque l'instance de la classe créée est appelée pour la première fois. Ensuite, si quelqu'un a besoin d'appeler la méthode Create, je, non, c'est le compilateur, juste. comme ce MOV dl, 0, de sorte que l'instruction de saut de jugement 0 dans le code (1) aille à l'endroit où elle devrait aller (Pourquoi dites-vous encore des bêtises ? La dernière fois, je le promets.) En fait, la méthode Create ici n'est qu'une méthode. méthode ordinaire, et , vous devez également remarquer que le premier appel à la méthode Create ou à la méthode NewInstance est la classe qui envoie ce message (notez que ce message n'est pas Message Windows, ce message n'est pas l'autre message, haha, c'est encore un non-sens, c'est vraiment la dernière fois, c'est vrai si vous ne comprenez pas le message ici, veuillez apprendre attentivement les connaissances en matière d'orientation objet et de modélisation) et appelez. plus tard. La méthode Create est un objet établi, Instance.Create(Self); bien sûr, la valeur du registre dl a changé.
D'accord, je n'ai pas beaucoup de temps. Enfin, je voudrais ajouter cela concernant le drapeau (la méthode de traduction de Taiwan, je pense que ce mot est bon, je vous suggère de l'utiliser aussi pour m'éviter bien des ennuis plus tard) et le instructions pour l'utilisation de ce registre dl, il faut dire qu'il n'y aura aucun changement. Si vous y réfléchissez bien, Delphi n'a pas changé de 1 à 6. D'ailleurs, cela prouve également que le concepteur HB de Delphi est un. personnage. Bien sûr, je ne peux pas comparer. Haha, c'est reparti, d'accord, j'arrête de parler. Oh, enfin, permettez-moi de dire que la méthode TObject.Create n'est en aucun cas une méthode vide, rappelez-vous, puis réfléchissez-y.
D'accord, d'autres choses, allez les voir en personne, dans ce cas, vous gagnerez beaucoup.
"Sortez d'ici, je veux voir et y réfléchir, et je ne veux pas de vos bêtises !" :)
au revoir
Lorsque le compilateur alloue de la mémoire pour un objet, le support qu'il fournit est d'insérer ces lignes de code assembleur avant d'appeler le constructeur :
tester dl, dl
jz +08$
ajouter des esp, -10$
call @ClassCreate // Faites attention à cette ligne de code
La dernière ligne du code ci-dessus appelle la fonction _ClassCreate à la ligne 8949 du fichier system.pas (sous réserve de Delphi 6). Cette fonction alloue spécifiquement la mémoire appropriée pour chaque objet. Une fois l’allocation de mémoire terminée, le constructeur de la classe est appelé pour initialiser les données membres. Ensuite, le compilateur insérera les lignes de code assembleur suivantes :
tester dl, dl
jz +0$f
appelez @AfterConstruction
pop dWord ptr fs : [$00000000]
ajouter des esp, 0c $
Le travail principal consiste à appeler AfterConstruction de chaque instance d'objet. Cet appel n'est d'aucune utilité dans Delphi. Son existence est réservée à C++Builder.
De même, lors de la destruction d'un objet, il faut d'abord appeler le destructeur de la classe pour libérer les ressources demandées par l'objet. Après cela, l'espace mémoire occupé par l'objet lui-même est recyclé. Ce travail est complété par le compilateur insérant le code assembleur suivant après avoir appelé le destructeur :
appelle @BeforeDestruction
tester dl, dl
jle +05$
appelez @ClassDestroy
Le travail effectué par ces codes correspond à ce qui est effectué lors de la construction de l'objet et de l'allocation de mémoire, en appelant principalement la fonction _ClassDestroy à la ligne 8997 dans system.pas.
Constructeur et destructeur
Pour définir un constructeur, utilisez le mot-clé Constructor. Par convention, le nom du constructeur est Create (bien sûr d'autres noms peuvent être utilisés, mais ce n'est en aucun cas une bonne conception !). comme:
taper
TMyFamily = class // La classe définie pour votre famille
Privé
FMyFatherName : String; // le nom de votre père
FMyMotherName : String; // le nom de votre mère
… // Autres membres de votre famille
Publique
Constructeur Create(strFatherName, strMotherName : String);
…… // Autres méthodes
Fin;
Vous vous demandez peut-être si je ne fournis pas de constructeur pour ma classe, ses objets peuvent-ils être créés ? La réponse est : oui. La raison a été évoquée précédemment, l'allocation de la mémoire occupée par l'objet lui-même est complétée par le compilateur. Et comme en Pascal Objet, toutes les classes (sauf la classe TObject elle-même) sont dérivées de la classe TObject, le compilateur appellera le constructeur TObject.Create(), mais cette fonction est une fonction vide, et elle n'affectera pas la classe TMyFamily. . Lorsque les données membres (FMyFatherName, FMyMotherName) sont initialisées, elles seront automatiquement effacées en chaînes vides (c'est-à-dire ''), car TObject.Create() ne connaît pas du tout votre père ou votre mère !
Lors de la création d'un objet, le constructeur est appelé directement, sous la forme suivante :
MyFamilyObject := TMyFamily.Create('Zhang', 'Li');
Utilisez le mot-clé Destructor pour définir un destructeur. Par convention, le destructeur est nommé Destroy. comme:
taper
TMaClasse = classe
Publique
Remplacement du destructeur Destroy();
Fin;
La raison pour laquelle l'instruction override est ajoutée à la fin de la déclaration du destructeur est de garantir que l'objet peut être détruit correctement dans le cas du polymorphisme (le polymorphisme sera discuté en détail dans la section 2.4). Si vous n'ajoutez pas le mot-clé override, le compilateur affichera un avertissement similaire à "La méthode 'Destroy' masque la méthode virtuelle de type de base 'TObject'". L'avertissement signifie que le Destroy que vous avez défini masque la méthode virtuelle TObject.Destroy() de la classe de base. Dans ce cas, l'objet ne peut pas être détruit correctement dans des situations polymorphes.
Remarque : les destructeurs doivent être déclarés avec une instruction override.
De même, si aucune ressource spéciale ne doit être publiée dans votre classe, vous n'avez pas besoin de définir un destructeur. Cependant, lors de la destruction d'un objet, vous devez appeler la méthode Free() de l'objet au lieu d'appeler directement Destroy().
MonObjetFamille.Free();
En effet, la méthode Free() déterminera si l'objet lui-même est nul, et s'il n'est pas nul, la méthode Destroy() de l'objet sera appelée pour augmenter la sécurité. Maintenant qu’il existe des moyens plus sûrs de le faire, il n’y a certainement aucune raison de ne pas le faire.
Remarque : n'appelez jamais Destroy() directement sur un objet, mais plutôt Free().
On peut en conclure qu'en Pascal Objet, il suffit de prêter attention à l'allocation et à la libération des ressources demandées par l'objet, et de ne pas se soucier de l'espace occupé par l'objet lui-même !