Autor Beitrag
flowstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 123

WinME
D6 Enterprise
BeitragVerfasst: Fr 19.03.04 18:08 
Ich hab mal ne Frage zur Delphi Syntax:
Warum heisst es bei der Erstellung von Instanzen
ausblenden Delphi-Quelltext
1:
Test := TKlasse.Create					

und nicht
ausblenden Delphi-Quelltext
1:
Test.Create					


Hat das nen sinn?


Zuletzt bearbeitet von flowstar am Fr 19.03.04 18:23, insgesamt 1-mal bearbeitet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 19.03.04 18:09 
Hallo!

Bitte ändere den Titel des Topics da er wenig über das eigentlich Thema verrät. Hier der entsprechende Absatz aus den Delphi-Forum.de Richtlinien:

Richtlinien hat folgendes geschrieben:

1.1 Beiträge
Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.[...]

Einfach oben bei deinem ersten Beitrag auf "Edit" klicken und den Titel ändern. Dank Dir!

Gruß Peter Lustig

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Fr 19.03.04 18:12 
Erstens mal ists keine blöde Frage sondern ein blöder Titel - bei sowas wundere dich nicht, wenn du in Zukunft keine Ahnung kriegst. Stehst sich schon auf der watchlist von einigen.

Zweitens ist Create ein constructor - der reserviert Speicher und gibt eine Referenz auf diese Objekt-Instanz zurück.

Wenn du xxx.Create schreibst, dann verwendest du bereits eine Instanz - die gibts aber noch nicht, weil Delphi keine statische Erzeugung von Objekten unterstützt. Somit hats du zu beginn nur eine ungültige Referenz-Variable, welcher du mit Create eine gültige zuweist.

//Edit: Die Mods sind aber heute wieder flott. :shock:

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
flowstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 123

WinME
D6 Enterprise
BeitragVerfasst: Fr 19.03.04 18:23 
Besser so?

Ihr seid heute aber mal wieder gut gelaunt...
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Fr 19.03.04 18:31 
::flowstar

Joo - das bin ich :lol: - weil in spätestens 3 Stunden und 30 Minuten bin ich dort: www.cosmiceye.org/party.htm - weil dort werden morgen sein, die da: www.astral-projection.com .
Womit eindeutig Schlußzufolgern ist: Es wird eine Menge netter, fescher, halbnackter Mädls dort auch sein - daher kann ich nur gut drauf sein ;-) .

Und weil ich beweisen will, daß ich sogar noch besser drauf sein kann als andere:
Hier der Beweis, daß wir gar nicht so übel sind: www.lugbz.org/docume...rt-questions_de.html

Frage übrigends beantwortet ?

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Fr 19.03.04 18:36 
Eigentlich ist es unlogisch. Denn, einerseits scheibe ich

ausblenden Delphi-Quelltext
1:
2:
var
  Bitmap: TBitmap;


und dann muß ich noch mal

ausblenden Delphi-Quelltext
1:
  Bitmap := TBitmap.Create;					


schreiben.

Was erwartet der Compiler wenn ich eine Bitmap Variable vom Typ TBitmap deklariere? Erwartet der, daß ich später ein Icon Objekt erstelle? Eigentlich ist es doppelte Pflege. Entweder einfach nur einen Zeiger deklarieren und erst später den Typ bei Create festlegen, oder beim deklarieren den Typ zuweisen und später einfach nur noch Create. Eine ander Möglichkeit hat man sowieso nicht, oder?

Oder kann einer genau sagen wieso es wichtig ist zwei mal drauf hinzuweisen was für Typ es ist?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 19.03.04 18:38 
Zitat:
//Edit: Die Mods sind aber heute wieder flott.
Möchtest Du damit dezent anmerken, dass wir manchmal nicht flott sind? ;-) :lol:

//edit:
Du kannst Deine Variable ja auch als Referenz auf ein bereits erzeugtes Objekt benutzen und musst dann gar kein neues Objekt erzeugen

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".


Zuletzt bearbeitet von Christian S. am Fr 19.03.04 18:40, insgesamt 1-mal bearbeitet
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Fr 19.03.04 18:40 
::bms

Du mußt den constructor sehen wie eine statische Methode - ähm - tschuldigung, Klassenmehtode heißts auf Delphisch.

Das heißt, bei Klassenmethoden gibts du ja auch die Klasse an Punkt Methode.

Mit der Variablendeklaration erzeugst du ja nur eine Referenz auf ein Objekt - und die weißt du später zu.

::peter

Hätte ich schreiben sollen zuuu flott ? *g*
Ich denke mal, daß besprechen wir mal lieber bei einem Bier ... ähm - aber dann bitte keine C/Delphi Performance Diskusssion - davon hatte ich heute schon genug ;-) .

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 19.03.04 19:47 
bms hat folgendes geschrieben:
Was erwartet der Compiler wenn ich eine Bitmap Variable vom Typ TBitmap deklariere? Erwartet der, daß ich später ein Icon Objekt erstelle?


Du übersiehst, dass jedes Objekt, das du erstellst, nicht nur einfach angelegter Speicher ist. Mit jedem Objekt verbunden sind Methoden, die vielleicht nur unter ganz bestimmten Bedingungen ausgeführt werden können.
Angefangen schon beim Konstruktor: Vielleicht braucht der eine bestimmte Variable oder ein anderes Objekt, wie einen Parent. Oder eine Prozedur muss vorher eine benötigte dll-Datei laden.
Da Delphi natürlich nicht wissen kann, wann es sicher ist, die Komponente zu erstellen, musst du es selber in deinem Code machen.

Da es in Delphi jedoch üblich ist, alle Variablen und Objekte, die du im Code nennen willst, vorher zu deklarieren, musst du vorher schon die Variable anlegen, in die dein Konstruktor dann die Komponente erstellen kann.
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Fr 19.03.04 19:50 
MaxiTB hat folgendes geschrieben:
Du mußt den constructor sehen wie eine statische Methode - ähm - tschuldigung, Klassenmehtode heißts auf Delphisch.

Das heißt, bei Klassenmethoden gibts du ja auch die Klasse an Punkt Methode.

Mit der Variablendeklaration erzeugst du ja nur eine Referenz auf ein Objekt - und die weißt du später zu.


Das Prinzip ist mir klar, nur erscheint es mir nicht logisch, daß es zwei mal sein muß. Allerdings kann ich mich damit abfinden, daß es bei Pascal so sein muß da es nicht anders ging (gemeint sind die Pascalkonventionen). Wenn ich zum Beispiel den Code-Vervollständiger nutze und hinter einer Bitmapvariable, d.h. hinter "Bitmap :=", STRG + LEERTASTE drücke, dann wird der korrekte Klassentyp angeboten (vorausgesetzt ich hab Bitmap als TBitamp deklariert). Delphi weiß also was kommen muß, verlangt aber dennoch das man TBitamp noch mal vor Create plaziert. Ich kann mir vorstellen, daß es auch anders und einfacher funktionieren könnte. Aber ich hab keine Probleme damit. Wenn aber eines sagen könnte wieso es so sein muß, dann wäere es nicht schlecht.
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 19.03.04 19:59 
Hallo???

Hast du meinen Post gelesen?

Na ja... schätze war gleichzeitig.
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Fr 19.03.04 21:08 
Eigentlich ist es egal und nicht so wichtig. Ich hab das Prinzip schon verstanden.

Es geht nicht drum, daß es gemacht wird. Die Frage ist also nicht warum man an erst an einer Stelle mit Create ein Objekt erstellt. Das sind nicht die Fragen. Die Frage ist wieso nicht einfach ein Create. Wieso haben die Entwickler von Delphi es so vorgesehen und nicht anders. Wieso nicht einfach ein

ausblenden Delphi-Quelltext
1:
2:
3:
4:
var
  Bitmap: TBitmap;
begin
  Bitmap.Create;


oder mindesten

ausblenden Delphi-Quelltext
1:
  Bitmap := Object.Create;					


Was kann es anderes sein als TBitmap. Eigentlich dürfte es kein Problem sein. Der Compiler weiß, daß es NUR TBitmap sein kann, da Bitmap vom Typ TBitmap ist.

Wenn ich es so mache.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
var
  Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;


dann schreibe ich zwei mal TBitmap, also ein mal doppelpflege.

Aber ich gehe davon aus, daß Delphi (oder genauer Pascal) nicht als Objektsprache entwickelt wurde. Deshalb hat man sich etwas zusammengeschustert was man noch als Pascal verkaufen konnte.
UC-Chewie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: Fr 19.03.04 21:19 
bms hat folgendes geschrieben:
Was kann es anderes sein als TBitmap. Eigentlich dürfte es kein Problem sein. Der Compiler weiß, daß es NUR TBitmap sein kann, da Bitmap vom Typ TBitmap ist.


Und genau da liegt dein Irrtum. Du kannst durchaus in dem von dir genannten Fall eine Instanz vom einer von TBitmap abgeleiteten Klasse erstellen. Das Stichwort dazu lautet Suche in: Delphi-Forum, Delphi-Library POLYMORPHIE bzw. Suche in: Delphi-Forum, Delphi-Library POLYMORPHISMUS, zu deutsch "Vielgestaltigkeit".

_________________
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 19.03.04 21:29 
Du kannst aber TBitmap.Create auch aufrufen, ohne das Ergebnis in eine Variable zu schreiben (das ginge sonst nicht).
Sinnvoll z.B. für Klassen, die sich sebst irgendwo registrieren.
Auch hat man so die Möglichkeit, für eine bestehende Instanz noch einmal Create ausführen zu lassen, ohne eine neue Instanz zu erstellen.

Nebenbei finde ich die Syntak eigentlich so ganz logisch und verstehe überhaupt nicht, weshalb du dich so aufregst...
Man ruft ja eine Funktion auf, nämlich den Konstruktor, und weist der Variablen auf der linken Seite deren Ergebnis zu (die neu geschaffene Instanz).
Vielleicht steht links bis jetzt nil, oder eine alte Referenz auf ein längst freigegebenes Objekt. Aber auf jeden fall steht da nichts nichts, mit dem ich etwas ausführen möchte, sondern etwas, von dem ich möchte, dass es überschrieben wird.
Für mich total logisch!!
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Fr 19.03.04 22:23 
Ok, lassen wir es. Anscheinend wird die Frage immer wieder mißverstanden. Ist auch nicht schlimm. Nur geht es mir die ganze Zeit um was anderes. Aber irgendwie kann ich nicht verständlich machen was ich meine. Ist egal.
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 20.03.04 08:38 
Was denn?
Du hast gefragt, warum man erst bei der Deklaration " : TBitmap" schreibt und dann beim Aufruf des Konstruktors nochmal " := TBitmap.Create ".

Genau das haben dir jetzt einige Leute beantwortet. Was daran jetzt noch falschverstanden werden könnte, ist mir nicht klar.

Ich stimme jetzt vielleicht so weit überein, dass man den Compiler auch hätte veranlassen können bei...
ausblenden Delphi-Quelltext
1:
2:
3:
Var Test:TBitmap;
...
Test:=Create;

...automatisch ein TBitmap zu erstellen. Trotzdem müsste dann aus genannten Gründen aber wenigstens die Möglichkeit bleiben, ein anderes Create aufzurufen.
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Sa 20.03.04 09:28 
Siehst du, über mehr wollte ich auch nicht diskutieren. Mir ist bewußt, daß es mehrere Konstruktoren geben kann und das einige Klassen auch mehrere Konstruktoren haben. Mir ist bewußt, daß es Polymorphie gibt und wozu sie dient. Mir ist auch bewußt, daß ich ein Objekt erstellen kann ohne eine Variable. Mir ist auch der Unterschied zwischen einer Variable, einer Klasse und einem Objekt bewußt. All das weiß ich und über das wollte ich auch nicht reden. Aber ich weiß von vielen Anfängern, durch vierschiedenen Forumsfragen, was viele gerade am Anfang für verwirend halten. Warum gerade so und nicht anders. Würde ich eine Objektorientierte Programmiersprache entwickeln, dann hätte ich einige anders gemacht. Ich hab mir mal Gedanken gemacht über Delphi und wie Delphi mit Objekten umgeht. Und meiner Meinung nach ist das nicht optimal. Es sieht irgendwie zusammengeschustert aus. Daruber wollte ich diskutieren, nur darüber.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Sa 20.03.04 14:05 
Es gibt einen Unterschied zwischen zwischen den beiden Aufrufen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  aBitmap: TBitmap;

aBitmap := TBitmap.Create;
aBitmap.Create;

Im ersten Fall wird Create als Constructor aufgerufen, also quasi als Klassenmethode die ohne ein Objekt auskommt. Stattdessen wird eben ein neues Objekt der angegebenen Klasse erzeugt und die Referenz darauf zurückgegeben.

Im zweiten Fall wird Create als Methode aufgerufen, und zwar nicht mehr als Klassenmethode, sondern als Methode das Objekts (in diesem Fall eben aBitmap). Es wird kein neues Objekt erzeugt, sondern es wird nur ganz normal der Code der Create-Methode abgearbeitet und in diesen Fall eben auf das Objekt bezogen über das die Methode aufgerufen wurde.

Das ist auch wichtig, dass es diese Unterscheidung gibt! Wenn du dich ein bisschen in OOP auskennst weißt du zB, dass man einen Konstruktor überschreiben kann und über inherited den geerbten Konstruktor aufrufen kann. zB:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
type
  TMyFirstClass = class(TObject):
    private
      F: Integer;
    public
      constructor Create(x: Integer); virtual;
  end;

  TMySecondClass = class(TMyFirstClass )
    public
      constructor Create(x: Integer); override;
  end;

constructor TMyFirstClass.Create(x: Integer);
begin
  inherited Create;
  F := x;
end;

constructor TMySecondClass.Create(x: Integer);
begin
  inherited Create(x);
  F := F + x;
end;


Stell dir nun vor es wird mit folgendem Code eine Instanz von TMySecondClass erstellt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var
  aObject: TMySecondClass;

aObject := TMySecconfClass.Create(5);

Was passiert da nun wirklich? Zuerst wird der Konstruktor von TMySecondClass aufgerufen und zwar als Konstruktor und nicht als Methode, es wird also eine Instanz von TMySecondClass erstellt und dann der Code des Konstruktors aufgerufen. Aber was passiert da in dieser Zeile?
ausblenden Delphi-Quelltext
1:
inherited Create(x)					

Hier wird der geerbte Konstruktor von TMyFirstClass aufgerufen, aber eben nicht als Konstruktor der ein neues Objekt erzeugt, sondern im Prinzip als normale Methode die sich auf das Objekt bezieht das der Konstruktor von TMySecondClass erstellt hat. Das muss ja auch so sein, da der geerbte Konstruktor dafür verantwortlich ist die geerbten Eigenschaften und Felder mit brauchbaren Werten zu füllen!

Ich hoffe das hilft dir ein bisschen das ganze zu verstehen, auch wenn das Beispiel vielleicht nicht ganz so gut zeigt was ich dir zu erklären versuche. Noch deutlicher wird das ganze wenn du mehrere verschiedene Klassen hast und jede mit mehreren verschiedenen Konstruktoren die sich untereinander selbst aufrufen und zwar sowohl von der eigenen Klasse als auch von den Basisklassen (wie ich es gerade in einem meiner Projekte habe). Aber so ein Beispiel hier anzuführen sprengt etwas den Rahmen und wäre auch zu kompliziert zum erklären...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 20.03.04 15:39 
Hm... das hatten ja schon mehrere oben erklärt, wenn auch keiner so ausführlich.

Also wenn ich flowstar jetzt richtig verstanden habe, dann ging es ihm auch gar nicht darum.
Er wollte nur wissen, warum es keine Kompilervereinfachung gibt, die es einem erspart, zwei mal TBitmap schreiben zu müssen.

Jetzt wo's hier aber alles schon mal so ausführlich steht, sollte man es vielleicht als gekürzte Fassung in die FAQ übernehmen.
Am besten gleich dazu beantworten, warum man mit TBitmap:=TBitmap keine Instanzen kopiert und warum und wann man Free aufrufen sollte.