| Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 13.07.09 20:47
mal eine frage zu klassen
normalerweise verwende immer Tx=class(TObject) private function xx(); usw.
jetzt arbeite ich aber mir jemand, der vorher c# gemacht hat und mir jetzt so was vorsetzt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TStartup = class class var Handle:HWND; public class procedure Startup(path:string;port:WORD);static; strict private class var BytesRead_:Cardinal; protected
end; |
er meint man kann dann mit z.b. TStartup.Startup('a\b',5025); die funktionen benutzen ohne (wie bei meiner variante) erst
Delphi-Quelltext 1: 2: 3: 4:
| var a:Tx; a:=Tx.Create; ... a.Free; |
zu benutzen
was ist der unterschied?
was macht class procedure anders als eine "normale" procedure?
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 13.07.09 21:08
Moin!
Eben genau das, du kannst die Methode direkt von der abstrakten Klasse aufrufen, ohne eine Instanz davon haben zu müssen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 13.07.09 21:30
ok und wie funktionert das, wenn ich z.b. ein dynamisches array darin habe?
das muss ich dann extra wieder freigeben, da es ja kein destroy gibt, richtig?
und das class procedure, muss das sein, oder reichts auch ohne class?
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 13.07.09 21:57
Moin!
Flamefire hat folgendes geschrieben : | ok und wie funktionert das, wenn ich z.b. ein dynamisches array darin habe?
das muss ich dann extra wieder freigeben, da es ja kein destroy gibt, richtig? |
Du kannst selbstverständlich nicht auf Eigenschaften einer abstrakten Klasse zugreifen; lokale Variablen einer Klassenmethode sind natürlich erlaubt und verhalten sich wie alle anderen lokalen Variablen auch.
Flamefire hat folgendes geschrieben : | | und das class procedure, muss das sein, oder reichts auch ohne class? |
AFAIK muss das class sein, woher soll der Compiler sonst wissen, dass es eine Klassenmethode ist.
Aber insgesamt bin ich nicht sonderlich bibelfest in ObjectPascal, wenn´s ganz in die Tiefe geht; ich halte z.B. delfiphan da eher für eine zuverlässige Quelle bezüglich Details in dieser Richtung.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Mo 13.07.09 22:12
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
jaenicke
      
Beiträge: 19335
Erhaltene Danke: 1751
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 14.07.09 04:16
Narses hat folgendes geschrieben : | | Du kannst selbstverständlich nicht auf Eigenschaften einer abstrakten Klasse zugreifen |
Doch, wenn es Klasseneigenschaften / Klassenvariablen sind wie oben im Quelltext.
Das alles kennst du vermutlich nicht, weil es das in Delphi 7 noch nicht gab. In Delphi 2006 / Turbo Delphi aber sehr wohl.
Der große Vorteil ist, dass man keine globalen Variablen nutzen muss, sondern z.B. für alle abgeleiteten Klassen z.B. etwas setzen kann. Und das eben direkt in der Klasse und nicht irgendwo als globale Variable, die nicht zur Klasse gehört.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 14.07.09 07:35
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 14.07.09 10:02
Mit Klassen-Methoden kann man bestimmte Operationen von einer bestimmten Klasseninstanz lösen. Dies ist z.B. dann interessant, wenn man eine bestimmte Arbeitsweise abgeschlossen zur Verfügung stellen möchte. Ein schönen Beispiel hierfür sind die Hash-Klassen im DEC (Delphi Encryption Compendium) von negaH (Hagen Reddmann), wo man einerseits einen Hash durch Instantiieren der Hash-Klasse, schreiben seiner Daten, Abschließen des Hashes, Auslesen des Ergebnisses, Konvertieren in das gewünschte Format, Freigeben des Hash-Objektes nutzen kann, oder durch Aufruf einer einfachen statischen Methode, die all dies für einen im Hintergrund kapselt und allein den zu bearbeitenden Puffer, dessen Länge und das Ausgabeformat benötigt.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mi 15.07.09 12:47
Rein technisch gesehen bringt es nichts wahnsinnig bahnbrechend Neues. Zur Laufzeit unterscheidet sich eine Klassenmethode eigentlich auch gar nicht wirklich von einer normalen Methode. Eine Methode kann demselben "of object"-Methoden-Typ zugewiesen werden, egal ob es sich um eine Klassenmethode oder normalen Methode handelt. Dabei zeigt Self bei einer normalen Methode auf das Objekt, und bei einer Klassenmethode auf die Klasse.
Die Klassen-Methoden braucht man, um gewisse OOP Patterns sauber implementieren zu können (z.B. Singleton). Eine Klassenmethode bietet zudem auch die Möglichkeit zur Vererbung (auch Klassenmethoden können virtual/override sein).
Möglich sind auch Klassen-Variablen, wobei ich hier im Zusammenhang mit Interfaces schlechte Erfahrungen gemacht habe.
|
|
jaenicke
      
Beiträge: 19335
Erhaltene Danke: 1751
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 15.07.09 17:33
delfiphan hat folgendes geschrieben : | | Möglich sind auch Klassen-Variablen, wobei ich hier im Zusammenhang mit Interfaces schlechte Erfahrungen gemacht habe. |
Dazu ist auch zu sagen, dass es bei Klasseneigenschaften z.B. bei D2006 (ich glaube bei allen Versionen) einen ( bekannten) Bug gibt, wodurch diese nur aus der selben Unit gesetzt werden können.
(Das nur so nebenbei, falls sich da jemand über einen internen Fehler oder so wundert, der dabei dann beim Kompilieren angezeigt wird.  )
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mi 15.07.09 21:22
Bei meinem Problem kam die Referenzzählung irgendwie durcheinander (sei es durch Memory-Corruption, Falschinitialisierung oder was auch immer. Die Ursache konnte ich nie finden). Meine Objekte wurden teilweise zu früh freigegeben, obwohl da noch Referenzen drauf waren; zum Teil wohl gar nicht freigegeben. Es war im Code kein offensichtlicher Bug zu finden. Es war alles high-level Code. Keine Pointer o.ä.. Gemeinsam war nur die Verwendung einer class var. Nachdem ich die durch eine globale Variable ersetzt hatte, ging alles wie gewünscht.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Do 16.07.09 17:20
hmm...
ich hab derzeit eine reader klasse
sie ist dafür da um daten aus einem packet, gegeben durch einen pointer und eine länge, zu lesen und zu schreiben
in der klasse wird mit beginread der interne pointer auf den anfang gesetzt und man kann mit z.b. readInt einen integer lesen
dabei wird klassenintern aus dem pointer gelesen und dann der pointer erhöht. (size checks inklusive)
sehr bequem
jetzt habe ich es (da ich es immer so gemacht habe) als class(TObject) gemacht und muss nun immer .create und .free verwenden
funktioniert soweit auch
könnte ich das ganze also stattdessen als klasse machen, indem ich das (TObject) wegmache und for alle "var" "function" und "procedure" in der declaration "class" schreibe?
dann dürfte sich das mit dem .create erledigt haben, oder?
bringt es tatsächlich vorteile, oder sollte ich lieber beim aktuellem bleiben?
|
|
jaenicke
      
Beiträge: 19335
Erhaltene Danke: 1751
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 16.07.09 18:41
Also alles als Klassenvariablen usw. ist nicht gerade OOP. Möglich ist es, aber ich würde nicht dazu raten.
Wenn du das Objekt einmal am Anfang erstellst, benutzt, und am Ende wieder freigibst, dann ist das ja auch wenig Aufwand. Du könntest (um es dir einfacher machen) auch eine Klassenfunktion erstellen, die (siehe das genannte Singleton-Pattern) eine Instanz der Klasse zurückgibt und ggf. vorher erstellt.
Die liegt dann in einer Klassenvariable und kann z.B. in finalization freigegeben werden.
Dadurch hättest du stets eine Instanz zur Verfügung, müsstest dich aber um nichts weiter kümmern, wenn du die verwendest. 
|
|
|