En Pascal Objet, tous les objets sont créés dans l'espace tas de la mémoire plutôt que sur la pile, donc le constructeur ne sera pas automatiquement appelé par le compilateur comme C++. La construction et la destruction d'objets relèvent de la responsabilité du programmeur.
Pour construire un objet, vous devez d'abord allouer de la mémoire à l'objet. Cette étape est prise en charge par le compilateur en Object Pascal - ce qu'on appelle la « Magie du compilateur ». Magic)", le programmeur n'a pas besoin de participer à ce processus ; alors les données membres de l'objet doivent être initialisées et le compilateur sera responsable de les "effacer", mais s'il y a une mission spéciale, elle peut être complétée dans le constructeur ; lorsque l'objet est détruit Les ressources demandées (et non la mémoire occupée par l'objet lui-même) doivent être libérées. Ces tâches sont de la responsabilité du destructeur, le recyclage de la mémoire occupée par l'objet lui-même est également effectué ; "magie du compilateur".
Allocation et recyclage de la mémoire objet
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 !