![]() |
Methode "Free" selbst implementieren (Assembler-Pr
Hallo,
Alle von TObject abgeleiteten Klassen können per Free freigegeben werden ohne das es zu einer Exception kommt falls das entprechende Objekt nicht instanziert wurde/nil ist. Ich möchte selbst ein Free implementieren ohne diese Eigenschaft zu verlieren. Bisher habe ich folgenden Code
Delphi-Quellcode:
Den Assembler-Code habe ich mir von TObject kopiert ohne wirklich zu wissen was er macht (wobei man die ersten beiden und letzten beiden Zeile ja erahnen kann). Das funktioniert auch soweit.
TMyList = class(TList)
protected FDoSomething : boolean; public destructor Destroy; override; procedure Free(DoSomething : boolean); reintroduce; end; destructor TMyList.Destroy; begin if FDoSomething then begin ...do something... end; inherited; end; procedure TMyList.Free(DoSomething: boolean); asm TEST EAX,EAX JE @@exit MOV ECX,[EAX] MOV DL,1 CALL dword ptr [ECX].vmtDestroy @@exit: end; Falls der Parameter "DoSomething" der Methode "Free" gesetzt (wahr) ist soll in "Destroy" entsprechend reagiert werden. Was ich jetzt nicht weiß ist wie ich meine Objektvariable in "Free" entsprechend dem Parameter setzen kann. Falls jemand eine Idee hat oder mir sagen kann wo ich sowas nachlesen kann oder einen einfacheren Ansatz hat würde ich mich freuen :lol: (Die Variable vor dem Aufruf von "Free" per property zu setzen würde sicher auch gehen, daß wollte ich aber vermeiden damit der Programmieren das nicht vergessen kann) Ciao |
Re: Methode "Free" selbst implementieren (Assemble
Wieso den komplizierten Assembler hernehmen? So gehts doch auch, und dein Problem löst es gleich mit :)
Delphi-Quellcode:
destructor TMyList.Destroy(DoSomething: boolean);
begin if Self <> nil then begin fDoSemthing := DoSomething; Destroy; end end; |
Re: Methode "Free" selbst implementieren (Assemble
1. Würde ich diese Funktion nicht Free nennen. Früher oder Später wird es nur Verwirrungen geben.
2. Kannst du ganz einfach mit
Delphi-Quellcode:
die Prüfung machen.
if Self=nil then
3. Entfällt 2 dann, weil du Free direkt aufrufen kannst, wenn du deiner Funktion einen anderen Namen gibts. |
Re: Methode "Free" selbst implementieren (Assemble
Schau mal dort rein, da dein Free jetzt einen Parameter besitzt, wird da vom Compiler noch zusätzlicher Code eingefügt, welcher jetzt vermutlich mit deinem AssemblerCode etwas in Konflickt gerät.
![]() (oder du hast einfach nur einen Fehler beim Abschreiben gemacht) |
Re: Methode "Free" selbst implementieren (Assemble
@Dax
In der Tat, einfacher geht es nicht.:wall: (Wobei ich dann die Prüfung in der Methode "Free" durchführe, aber ich denke das wolltest du auch schreiben da du innerhalb des if-Blockes ja Destroy aufrufst) Als ich rumgetestet habe und noch Pascal statt Assembler verwendete hatte ich Free wohl noch als virtual gekennzeichnet. Von daher ging das nicht (Exception beim Aufruf ohne in die Methode zu springen). Dann habe ich wohl den Assembler-Code kopiert und das virtual entfernt und die Schuld fälschlicherweise auf den Pascal-Code geschoben) @jim_raynor Mein Gedanke bei der Benennung der Methode war halt der, daß jeder weiß, daß er ein instantiertes Objekt wieder mit Free freigeben muß. Wenn man dieses Objekt benutzt und Free aufruft meckert dann der Compiler, daß der Parameter fehlt. So weiß derjenige dann: 1. ja, er muß Free aufrufen 2. zum Aufruf ist ein Parameter nötig (der dann natürlich nicht DoSomething heißt sondern erkennen läßt was er tut!) Natürlich fehlt dann hier noch "inherited Free;", sodaß meine Methode jetzt so aussieht:
Delphi-Quellcode:
Deshalb habe ich ja auch "Free" mit reintroduce" gekennzeichnet. Somit gibt es nur das eine "Free" und Verwirrungen sind somit minimiert. (Zumindest würde es mich mehr verwirren wenn es auf einmal 2 Free-Methoden gibt!)
procedure TMyList.Free(ADoSomething: boolean);
begin if Self <> nil then begin FDoSomething := ADoSomething; inherited Free; end; end; Ich denke so sollte das gehen. Falls noch Einwände bestehen würde ich mich über Eure Meinung freuen. PS: Vielen Dank für die superkurze Antwortzeit! |
Re: Methode "Free" selbst implementieren (Assemble
@himitsu
Noch ein Grund das ohne Assembler zu lösen :wink: Wie gesagt, ich habe keine Ahnung von Assembler. |
Re: Methode "Free" selbst implementieren (Assemble
Benenne die Methode trotzdem nicht Free, weil Free von Delphi an den verschiedensten Stellen genutzt wird und dabei von der Festen "Methoden-Signatur" ohne Parameter ausgegangen wird. Wenn die Free jetzt Parameter gibt (warum eigentlich), dann machst Du es für andere Entwickler nur umständlicher mit Deinen Objekten zu arbeiten.
...:cat:... |
Re: Methode "Free" selbst implementieren (Assemble
Aber warum willst du eigentlich ein eigenes Free ? :gruebel:
|
Re: Methode "Free" selbst implementieren (Assemble
@Neutral General
Zitat:
@sakura Zitat:
|
Re: Methode "Free" selbst implementieren (Assemble
Folgende "einfache" Lösung ist auch möglich.
Delphi-Quellcode:
Dann kannst Du einfach mit folgenden Zeilen Deinen Zweck erfüllen.
TMyList = class(TList)
public DoSomething : boolean; destructor Destroy; override; end; destructor TMyList.Destroy; begin if DoSomething then begin ...do something... end; inherited; end;
Delphi-Quellcode:
Die "ml := Nil" Zeile habe ich mir angewöhnt, da ein Free prüft ob das Objekt <> nil ist und es in diesem Fall freigibt. Danach ist aber das Objekt zwar freigegeben, aber nicht nil. Der Pointer zeigt immer noch auf die Spericherstelle wo das Objekt mal war. Ein erneuter Aufruf von Free kann dann Probleme machen.
...
var ml : TMyList; ... begin ... ml := TMyList.Create; ... ml.DoSomething := True; ... ml.Free; ml := Nil; ... end; ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz