Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Prozedur, Constructor
Grafix - Mi 25.03.09 21:09
Titel: Prozedur, Constructor
Hey,
ich weiß, ich weiß, ihr habt schon 1000 mal erklärt wie OOP funktioniert, und wo man entsprechende Lektüren im Internet finden kann, jedoch kann ich daraus nicht verstehen, was das mit diesem Constructor wirklich auf sich hat, bzw worin der unterschied zwischen procedure, function und constructor besteht. Ich schreibe am Montag mein Abi im InfoLK, meine Stärke liegt jedoch gewiss nicht auf OOP :(
Danke für eure Hilfe!
mfG
Chris
Xentar - Mi 25.03.09 21:13
constructor wird aufgerufen, um eine Instanz einer Klasse zu erzeugen, also normalerweise "Create".
Passend dazu gibts auch den Destructor, standardmäßig "Destroy".
Grafix - Mi 25.03.09 21:17
jep, so stets überall...
aber wie ist das in dem entsprechenden Beispiel?:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| TDatensatz = class filmID: string; title: string; regisseur: string; constructor create (f, t, r: string); end;
constructor TDatensatz.create(f,t,r: string); begin filmID := f; titel := t; regisseur: r; end; |
was genau bedeutet der constructor in TDatensatz, und wieso schreibe ich beim zweiten CodeSchnippsel constructor statt procedure?!
Yogu - Mi 25.03.09 21:23
In deinem Beispiel macht der Konstruktor wirklich keinen Sinn, denn da fehlt eine wichtige Zeile:
Delphi-Quelltext
8: 9: 10: 11: 12: 13: 14:
| { ... } constructor TDatensatz.create(f,t,r: string); begin inherited Create; filmID := f; titel := t; regisseur: r; end; |
Ein Konstruktor reserviert den nötigen Speicher für das Objekt und initialisiert es. Das macht bereits der Konstruktor der Klasse
TObject. Alle abgeleiteten Klassen erweitern ihn. Ein Zeiger auf die neue Instanz wird zurückgegeben, also wäre ein Konstruktor eher mit einer Funktion als einer Prozedur vergleichbar.
Grafix hat folgendes geschrieben : |
| was genau bedeutet der constructor in TDatensatz, und wieso schreibe ich beim zweiten CodeSchnippsel constructor statt procedure?! |
Welcher zweite Codeschnipsel? :gruebel:
Grafix - Mi 25.03.09 21:28
Lol, das ist ein Ausschnitt aus eine Abituraufgabe, der zu analysieren ist, ich habe ihn 1:1 übernommen...
inherited bedeutet geerbt oder? wieso Create? (Fragen über Fragen^^)
Yogu hat folgendes geschrieben : |
| also wäre ein Konstruktor eher mit einer Funktion als einer Prozedur vergleichbar. |
das ist ja meine Frage, woher weiß ich wann ich constructor, procedure oder function verwenden muss?
-> mit dem zweiten Codeschnippsel meinte ich das constructor TDatensatz.create...
schon mal danke für eure Hilfe!!!
Yogu - Mi 25.03.09 21:36
Grafix hat folgendes geschrieben : |
| Lol, das ist ein Ausschnitt aus eine Abituraufgabe, der zu analysieren ist, ich habe ihn 1:1 übernommen... |
:rofl: (Sollen die ruhig mal probieren, da kommt AFAIK eine Zugriffsverletzung ;))
Grafix hat folgendes geschrieben : |
| inherited bedeutet geerbt oder? wieso Create? (Fragen über Fragen^^) |
Ok, nochmal von vorne.
TObject hat einen Konstruktor namens Create. Dieser initialisiert das Objekt. TDatensatz überschreibt ihn. Überschreiben heißt erst einmal komplett löschen und neu schreiben. Damit der alte Code nicht verloren geht muss er per
inherited Methodenname; aufgerufen werden - die Methode heißt in diesem Fall Create.
Yogu hat folgendes geschrieben : |
| woher weiß ich wann ich constructor, procedure oder function verwenden muss? |
Ganz einfach:
Create ist ein Konstruktor,
Destroy ein Destruktor und alle anderen sind Prozeduren und Funktionen (den Unterschied kennst du aber, oder?).
JayEff - Mi 25.03.09 21:37
Yogu hat folgendes geschrieben : |
Delphi-Quelltext 8: 9: 10: 11: 12: 13:
| { ... } TDatensatz = class filmID: string;
constructor TDatensatz.create(f,t,r: string); begin inherited Create; | |
Von was soll Create denn geerbt werden, wenn die Klasse keinen Vorfahren hat? :nixweiss:
Yogu - Mi 25.03.09 21:38
Alle Klassen sind von
TObject abgeleitet - und da steht jede Menge (vielleicht auch magischer) Code im Konstruktor.
JayEff - Mi 25.03.09 21:39
Yogu hat folgendes geschrieben : |
Alle Klassen sind von TObject abgeleitet - und da steht jede Menge (vielleicht auch magischer) Code im Konstruktor. |
Hm, das mag sein, damit hab ich mich nie groß beschäftigt. Ist auch irgendwie logisch, dass der Konstruktor ohne die ganze Magie nicht funktioniert :motz:
Grafix - Mi 25.03.09 21:43
constructor bedeutet also nur, dass TDatensatz initialisiert wird und in diesem Constructorbereich können Variablen deklariert werden, oder? Das heißt nach Constructor muss immer entweder Create oder Destroy stehen?
Gibts irgendwo im Netz ein Tutorial, dass OOP Schritt für Schritt an Beispielen LEICHT verständlich erklärt?^^
Yogu - Mi 25.03.09 21:49
Yogu hat folgendes geschrieben : |
Grafix hat folgendes geschrieben : | | Lol, das ist ein Ausschnitt aus eine Abituraufgabe, der zu analysieren ist, ich habe ihn 1:1 übernommen... |
:rofl: (Sollen die ruhig mal probieren, da kommt AFAIK eine Zugriffsverletzung ;)) |
Ok, ich nehm alles zurück - das klappt tatsächlich (Delphi 2005). :oops:
Wahrscheinlich steckt die Magie einfach im Konstruktor.
Ich hab mal versucht, einen Konstruktor zu basteln, der aus einer Funktion besteht. Erste Möglichkeit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| type TMyObject = class public MyVar: Integer;
function MyCreate: TMyObject; end; |
Problem beim Aufruf: Die Funktion ist nur für initialisierte Objekte gültig, ein
TMyObject.MyCreate geht nicht.
Zweiter Versuch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| type TMyObject = class public MyVar: Integer;
class function MyCreate: TMyObject; end; |
Es gibt ein
Self und folglich kann auch nichts initialisiert werden.
Fazit: Ein Konstruktor ist eine
class function, die aber eine Instanz von sich selbst erzeugt und darauf zugreifen kann.
Grafix hat folgendes geschrieben : |
| constructor bedeutet also nur, dass TDatensatz initialisiert wird und in diesem Constructorbereich können Variablen deklariert werden, oder? |
Genau. :zustimm:
Grafix hat folgendes geschrieben : |
| Das heißt nach Constructor muss immer entweder Create oder Destroy stehen? |
Create ja, Destroy nein: Dafür gibts
destructor.
Grafix hat folgendes geschrieben : |
| Gibts irgendwo im Netz ein Tutorial, dass OOP Schritt für Schritt an Beispielen LEICHT verständlich erklärt?^^ |
DELPHI OOP TUTORIAL ;)
Erstes Ergebnis:
Delphi-Tutorials - OOP in Delphi [
http://www.delphitutorials.de/oop-in-delphi.html].
Grafix - Mi 25.03.09 21:52
hey, unterstell mir nicht ich hätte nicht auch in Google gesucht, meinem Freund und Helfer, ich war sogar schon auf der Seite, habe aber nur den riesen Codeschnippsel gesehn und bin schnell wieder geflohen^^
Danke für die Hilfe, werde mich mal am Tutorial versuchen.
Super Forum!
Yogu - Mi 25.03.09 21:55
Grafix hat folgendes geschrieben : |
| ich war sogar schon auf der Seite, habe aber nur den riesen Codeschnippsel gesehn und bin schnell wieder geflohen^^ |
Das hätte ich auch fast, bis ich bemerkt habe, dass Google auf Seite 9 verlinkt. Versuch dich mal am Anfang des Tutorials ;)
Grafix - Mi 25.03.09 22:15
kleine Zwischenfrage, was bedeutet FValue: Currency?
Marc. - Mi 25.03.09 22:19
Grafix hat folgendes geschrieben : |
| kleine Zwischenfrage, was bedeutet FValue: Currency? |
Deklariert eine Feld-Variable vom Typ Currency:
| DOH hat folgendes geschrieben: |
| Der Typ Currency ist ein Festkomma-Datentyp, der Rundungsfehler in finanzmathematischen Berechnungen minimiert. In Win32 wird er als skalierter 64-Bit-Integer gespeichert, bei dem die vier niedrigstwertigen Stellen implizit vier Nachkommastellen repräsentieren. Bei einer Kombination mit anderen reellen Typen in Zuweisungen und Ausdrücken werden Currency-Werte automatisch mit 10000 multipliziert. |
Mehr dazu findest Du in Deiner Delphi-Online-Hilfe. (Mauszeiger über das Codewort halten und F1 drücken)
der organist - Mi 25.03.09 22:20
Grafix hat folgendes geschrieben : |
das ist ja meine Frage, woher weiß ich wann ich constructor, procedure oder function verwenden muss?
|
Naja, bevor du ein Objekt benutzen kannst, muss du es am Anfang erzeugen. Mit einem constructor. Danach kannst du ganz normal Prozeduren benutzen. Am Ende musst du noch noch den Speicherplatz freigeben, so dass keine "Speicherlöcher" (unbenutzbarer Speicher" entstehen.
Ob nun ein Constructor mehr Funktion als Prozedur ist, lass ich mal außen vor, dann kann ich einfach keine Senf zu geben, aber im Gegensatz zu einer normalen prozedur wird zusätzlich das Objekt erzeugt, selbiges beim destructor.
Deine Zwischenfrage kann ich leider nicht beantworten.
EDIT: Da war wohl jemand schneller
EDIT: ich füg mal noch etwas mehr Erklärung hinzu...
Ah und dann fehlt noch, was eine Funktion ist und der Unterschied von ner Proc. und Func.:
in einer Prozedur (so mach ich das zumindest) kannst du Werte verändern, auch Ereignisse wie Buttonklicks reagieren etc. Eine Funktion hingegen, naja, was ist eine mathematische Funktion? Du gibst einen x-Wert und bekommst nen y-Wert zurück. In Delphi gibst du der Funktion ein Argument und bekommst danach einen Wert zurück. Das kann sein wie in einer (hier selbstdefinierten Funktion (bitte bei Fehlern drauf hinweisen, ich probier das jetzt ncih in Delphi aus):
Delphi-Quelltext
1: 2: 3: 4:
| function Multiply (AFactor1, AFactor2, AFactor3:Extended):Extended; begin Multiply:=AFactor1*AFactor2*AFactor3; end; |
Wenn du die Funktion aufrufst, wie im folgenden Beispiel, erhälst du das Produkt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure myButton.Click(Sender:TObject); begin Label1.Caption:=FloatToStr(Multiply(StrToFloat(Edit1.Text), StrToFloat(Edit2.Text), StrToFloat(Edit3.Text))); end; |
danach wird dir im Label das Multiplikationsergebnis angezeigt. In diesem beispiel ist es eigentlich total simpel, die ganze Sache ohne Funktion zu schreiben, aber es gibt ein paar Sachen, die (a) wesentlich schwieriger sind und [b] teilweise schon von Borland (?) vorgefertigt sind:
Delphi-Quelltext
1: 2: 3:
| FormatDateTime(,);
DayOfTheYear(); |
Beispiel für einen Constructor, meist ist es nützlich einen zu schreiben (weil man dort z.B: Startwerte zuweisen kann...ohne nachher auf die Felder (Variablen, Arrays , wie auch immer ) direkt zuzugreifen, so dass man diese privat deklarieren kann):
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| constructor TPlayer.Create(AName:String;APoints:Integer); begin SetLength(Islands,0); Points:=APoints; Name:=AName; end; |
Hoffe es ist etwas verständlicher geoworden. Diejenigen, die noch erfahrener sind, mögen mich korrigieren, wenn nötig.
Grafix - Mi 25.03.09 23:17
danke für eure schnellen und ausführlichen antworten! habt mir wirklich geholfen, versuche mich dann mal weiter am Tutorial
jaenicke - Mi 25.03.09 23:27
Yogu hat folgendes geschrieben : |
Alle Klassen sind von TObject abgeleitet - und da steht jede Menge (vielleicht auch magischer) Code im Konstruktor. |
Du hast es ja auch selbst schon festgestellt, aber ich wollte dir den magischen Code nicht vorenthalten: :mrgreen:
Delphi-Quelltext
1: 2: 3:
| constructor TObject.Create; begin end; |
Da der Konstruktor nicht als virtuell gekennzeichnet ist, kannst du den auch nicht überschreiben sondern musst ihn normal neu schreiben.
Trotzdem ist das inherited sinnvoll, z.B. wenn man mal die Klasse ändert, von der abgeleitet wurde. ;-)
Yogu - Do 26.03.09 16:51
der organist hat folgendes geschrieben : |
| Ah und dann fehlt noch, was eine Funktion ist und der Unterschied von ner Proc. und Func.: |
Wetten, ich schaffe es
etwas kürzer zu erklären?
Eine Funktion kann Werte zurückliefern. :mrgreen:
Gut, mit magischem Code meinte ich ja auch kein Delphi-Quelltext, sondern Compiler Magic. Die sieht man recht schlecht in der Quelldateien und befindet sich schon im Schlüsselwort
constructor ;)
jaenicke hat folgendes geschrieben : |
| Da der Konstruktor nicht als virtuell gekennzeichnet ist, kannst du den auch nicht überschreiben sondern musst ihn normal neu schreiben. |
Was ja irgendwie auf das gleiche rauskommt, oder? Außer natürlich dem fehlenden
override.
jaenicke hat folgendes geschrieben : |
| Trotzdem ist das inherited sinnvoll, z.B. wenn man mal die Klasse ändert, von der abgeleitet wurde. ;-) |
Deshalb ist es auch gut, sich ein
inherited Create; anzugewöhnen - wenn man später die Elternklasse ändert, denkt man unter Umständen nicht daran, den Konstruktor anzupassen. :idea:
Zorro - Do 26.03.09 18:15
der organist hat folgendes geschrieben : |
Ob nun ein Constructor mehr Funktion als Prozedur ist, lass ich mal außen vor, dann kann ich einfach keine Senf zu geben, ...
|
Ist (wenn man das denn überhaupt einstufen will) als Funktion einzustufen, da der Constructor das soeben erzeugte Objekt zurückgibt:
MyObj := TMyOb.Create(nil);
Greetz
Zorro
jaenicke - Do 26.03.09 18:17
Genau gesagt würde ich es als spezielle class function bezeichnen. ;-)
delfiphan - Do 26.03.09 20:24
der organist hat folgendes geschrieben : |
| ... aber im Gegensatz zu einer normalen prozedur wird zusätzlich das Objekt erzeugt, selbiges beim destructor. |
Jein; wird der Konstruktor über eine Objektreferenz aufgerufen bzw. über Self, wird kein neues Objekt mehr erzeugt. Es gibt eine Fallunterscheidung. Nicht immer "kreiert" der Konstruktor was.
Im Übrigen ruft der Konstruktur auch NewInstance und AfterConstruction und besitzt einen Exception-Handler, der dafür sorgt, dass im Fehlerfall der Destruktor aufgerufen wird.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!