Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Assigned (https://www.delphipraxis.net/28555-assigned.html)

Pseudemys Nelsoni 26. Aug 2004 11:30


Assigned
 
hoi,

ja ich weiss, wurde in einem anderem thread (nebenbei) erklärt, aber ich versteh diese funktion nicht ganz....das heisst wie sie funktioniert weiss ich schon, nur die verwendung versteh ich bei einigen sachen nicht. Gerade in der klassenprogrammierung wie z.b das hier:

Delphi-Quellcode:
procedure TNumEdit.KeyPress(var Key: Char);
begin
  if not Key in ['0'..'9'] then
  begin
    if Assigned(OnFehler) then
      OnFehler(Self);
    key:=#0;
  end;
  inherited KeyPress(Key);
end;
( Source: http://www.delphi-treff.de/content/t...dex.php4?kat=6 )


ich weiss das assigned true ist wenn OnFehler nicht nil ist, aber ich verstehe nie WANN hier OnFehler nil ist und wann nicht und wie es hier geprüft wird...ich verstehs irgendwie alles nich mit dieser doofen funktion :?

Sanchez 26. Aug 2004 11:42

Re: Assigned
 
Hallo,

Eine Membervariable einer Klasse ist von "Natur aus" nicht zugewiesen. D.h. Integers sind 0, Strings sind Leerstrings und Pointer sind nil, usw ...

Die Funktion Assigned überprüft jetzt, ob der Parameter <> nil ist.
Der Pointer OnFehler ist also am Anfang nil. Wenn er erstmalig zugewiesen wird, zeigt er nicht mehr auf nil, sondern irgendwo in den Speicher. Jetzt gibt Assigned(OnFehler) true zurück.

Nachdem du das nächste mal OnFehler nil zuweist, wird Assigned wieder false zurückgeben.

Wenn du jetzt allerdings ein erzeugtes Objekt mit Free freigibst, wird Assigned trotzdem true zurückliefer, weil der Pointer noch irgendwo in den Speicher zeigt.

z.B.
Delphi-Quellcode:
var Liste : TStringlist;
begin
  Liste := TStringlist;

  Liste.Free;

  if Assigned(Liste) then begin
    Liste.Add('abc'); //<-- hier gibts ne AV
  end;
end;
Deshalb sollte man statt .Free FreeAndNil() verwendet, weil es der Variable gleich nil zuweist.

Ich hoffe das war verständlich.

grüße, daniel

[EDIT] Hoppla, bei den Tags verklickt [/EDIT]

Chewie 26. Aug 2004 11:43

Re: Assigned
 
OnFehler ist wohl ein Event. Events sind nichts weiter als Zeiger auf Methoden, die meist als Properties implementiert sind. Beim Erzeugen des Objekts existieren keine Ereignisbehandlungsroutinen, OnFehler ist also nil. Erst wenn eine Behandlungsroutine gesetzt wird (MyObject.OnFehler := MyEventHandler), ist Onfehler nicht mehr nil. Durch die Prüfung mit Assigned wird Onfehler also nur aufgerufen, wenn es auch gesetzt ist.

Treffnix 26. Aug 2004 11:45

Re: Assigned
 
OnFehler wird ein Event der Klasse TNumEdit sein. Das heisst, es ist eine Procedure of object, die von ausserhalb erst zugewiesen werden kann ( nicht muss ).

Beispielsweise wie das onClick eines Buttons.
Wenn dem Ereignis keine Prozedur zugeordnet ist, ist das Event nil. Würde man versuchen eine nichtexistente Prozedur aufzurufen, gäbs ne Exception. Daher muss man das vorher prüfen.

Pseudemys Nelsoni 26. Aug 2004 11:57

Re: Assigned
 
Hallo Sanchez,

danke für die ausführliche beschreibung;), soweit hatte ich das auch schon verstanden. Ich verstehe es nur nicht wieso es in meinem beispiel benutzt wird (klar verstehe ich es das assigned da prüft ob OnFehler<>nil ist)... ich kapiers irgendwie nicht....fragen wir mal anders...wieso sollte der geprüfte methodenzeiger denn nil sein? sorgt man beim programmieren nicht sowieso vorher dafür das das ding irgendwo hinzeigt bevor man es benutzt(womit aissgned überflüssig wäre)?

Zitat:

OnFehler ist wohl ein Event. Events sind nichts weiter als Zeiger auf Methoden, die meist als Properties implementiert sind. Beim Erzeugen des Objekts existieren keine Ereignisbehandlungsroutinen, OnFehler ist also nil. Erst wenn eine Behandlungsroutine gesetzt wird (MyObject.OnFehler := MyEventHandler), ist Onfehler nicht mehr nil. Durch die Prüfung mit Assigned wird Onfehler also nur aufgerufen, wenn es auch gesetzt ist.
wer setzt denn OnFehler? ich dachte eigentlich das man das bereits in der klasse alles drin hat hm.

Zitat:

OnFehler wird ein Event der Klasse TNumEdit sein. Das heisst, es ist eine Procedure of object, die von ausserhalb erst zugewiesen werden kann ( nicht muss ).
was heisst das von ausserhalb? wenn ich z.b eine komponente habe , dann im OI irgendeinem ereignis ein code hinzufüge...ist das mit zuweisen gemeint?

Delphi-Quellcode:
Beispielsweise wie das onClick eines Buttons.
Wenn dem Ereignis keine Prozedur zugeordnet ist, ist das Event nil. Würde man versuchen eine nichtexistente Prozedur aufzurufen, gäbs ne Exception. Daher muss man das vorher prüfen.
Genau das ist irgendwie meine Frage, wieso sollte ich in meiner klasse versuchen die prozedur aufzurufen wenn sie nicht da ist. ich meinte wer tut denn das hmmm.

hab da so ne theorie... ist das so gemeint, das wenn ich bei einem button z.b kein OnClick ereignis definiert habe und dann versuche mit button1.click die procedure aufzurufen? oder wie?

danke für eure antworten :oops:

Treffnix 26. Aug 2004 12:04

Re: Assigned
 
Stell dir vor, TButton wurde von dir programmiert. Du weisst, wann der Benutzer auf den Button klickt. Was machst du nun? Du animierst den Button erstmal ein bisschen, damit es nach Klick aussieht und nun? Woher weisst du, was der Programmierer machen will, wenn einer auf den Button klickt? - Du schaust nach, ob dem OnClick-Event eine externe Prozedur zugewiesen ist. Wenn ja, rufst du sie auf.

Nichts anderes ist das bei dem OnFehler. Dem Event muss keine Prozedur zugewiesen sein, aber vielleicht will der Programmierer, der deine Komponente benutzt ja im Fehlerfall reagieren, z.B. eine Fehlermeldung ausgeben. Dann kann er dem Event eine Prozedur zuweisen, in der er das macht.

Steve 26. Aug 2004 12:04

Re: Assigned
 
Hi,

nimm als Beispiel mal TButton.OnClick her...

Solange Du dem OnClick nichts zuweist (z.B. PROCEDURE TForm1.Button1Click(Sender: TObject); ), wird bei einem Klick darauf nichts ausgeführt, da Assigned(OnClick)=NIL (Genauer: in TControl Assigned(FOnClick)) ist.

Gruß
Stephan

{edit: wiedermal zu langsam :mrgreen: }

Pseudemys Nelsoni 26. Aug 2004 12:12

Re: Assigned
 
Zitat:

Du schaust nach, ob dem OnClick-Event eine externe Prozedur zugewiesen ist. Wenn ja, rufst du sie auf.
das meine ich ja, wann genau tu ich denn das? ich meine im OnClick selbst brauch ich das ja nicht prüfen ob assigned ist, weil doe prozedur ja nur aufgerufen wenn überhaupt etwas in der OnClick routine ist, oder?


Zitat:

Solange Du dem OnClick nichts zuweist (z.B. PROCEDURE TForm1.Button1Click(Sender: TObject); ), wird bei einem Klick darauf nichts ausgeführt, da Assigned(OnClick)=NIL (Genauer: in TControl Assigned(FOnClick)) ist.
gleiche frage wie oben, wo und wann wird das geprüft :oops: :oops: :oops:

woki 26. Aug 2004 12:14

Re: Assigned
 
Zitat:

Zitat von Pseudemys Nelsoni
hab da so ne theorie... ist das so gemeint, das wenn ich bei einem button z.b kein OnClick ereignis definiert habe und dann versuche mit button1.click die procedure aufzurufen? oder wie?

Eben.

Hinter jedem Event im Objektinspector steht ein Methodenzeiger, fast alle davon sind nil, bzw sind nil bis du einen Eventhandler implementierst. Die Abfrage prüft also, ob ein Eventhandler, der ausgeführt werden soll, zugewiesen wurde. Diese Architektur macht Klassen viel flexibler einsetzbar, als wenn man immer eine neue Klasse ableiten müßte, um Änderungen bei der Behandlung von events zu implementieren. Und wie könnte soetwas wie Delphi sonst funktionieren?

Grüsse
Woki

Treffnix 26. Aug 2004 12:19

Re: Assigned
 
Zitat:

Zitat von Pseudemys Nelsoni
das meine ich ja, wann genau tu ich denn das? ich meine im OnClick selbst brauch ich das ja nicht prüfen ob assigned ist, weil doe prozedur ja nur aufgerufen wenn überhaupt etwas in der OnClick routine ist, oder?

Eben. Sonst gibts nen Fehler. Und genau deshalb musst du das prüfen.
Du befindest dich aber ( im Beispiel ) innerhalb der TButton-Klasse. Das OnKlick ist ein Property, das von dir nach aussen gelegt wird. Und erst wenn jemand, der eine Instanz deiner Klasse erzeugt, diesem Property etwas zugewiesen hat, kannst du die zugewiesene Prozedur auch aufrufen. Im Falle des Buttons geschieht das, wenn du feststellst, dass der Benutzer mit der Maus auf deinen Button klickt. In deinem Beispiel wäre das sobald deine Klasse einen Fehler feststellt.

Pseudemys Nelsoni 26. Aug 2004 12:23

Re: Assigned
 
Danke für die Hilfe, ich glaub ich verstehs 8)

Wenn nicht, schreib ich in 24std nochmal *g*

Steve 26. Aug 2004 12:25

Re: Assigned
 
Bissl vereinfach passiert folgendes: TControl "empfängt" eine Message vom Betriebssystem, dass bspw. ein Mausklick ausgeführt wurde. TControl prüft, ob dieser klick "auf" sich bzw. in seinem Anzeigebereich ausgeführt wurde. Falls ja, wird "TControl.Click" ausgeführt. Innerhalb dieser 'Procedure' wiederum wird besagte Assigned(FOnClick)-Prüfung durchgeführt. ;)

mytar 26. Aug 2004 13:58

Re: Assigned
 
Du kannst folgende Varianten verwenden:

Delphi-Quellcode:
if OnFehler <> nil then
oder besser

Delphi-Quellcode:
if Assigned(OnFehler) then

Muetze1 26. Aug 2004 14:31

Re: Assigned
 
Moin!

Mal so nebenbei zu dem Source:

1. Ihr achtet doch so alle auf den Style: Warum wird innerhalb der Komponente auf die Property zugegriffen? Das ist doch mehr als böse und vor allem langsam...
2. Warum prüft If Assigned(OnError) Then nicht einfach die Variable die die Objektmethode enthält? (Also If Assigned(FOnError) Then??)
3. Warum ist in dem Edit kein Backspace erlaubt vom Code her?

MfG
Muetze1

Treffnix 26. Aug 2004 14:41

Re: Assigned
 
Zitat:

Zitat von Muetze1
Moin!

Mal so nebenbei zu dem Source:

1. Ihr achtet doch so alle auf den Style: Warum wird innerhalb der Komponente auf die Property zugegriffen? Das ist doch mehr als böse und vor allem langsam...
2. Warum prüft If Assigned(OnError) Then nicht einfach die Variable die die Objektmethode enthält? (Also If Assigned(FOnError) Then??)
3. Warum ist in dem Edit kein Backspace erlaubt vom Code her?

MfG
Muetze1

Der Code kommt doch nichtmal von hier, sondern von nem Tutorial bei delphitreff.
Die private Methode könnte ja OnError heissen ( ich weiss, ist nicht so ) :tongue:
Ist doch nur ein Beispiel, dessen Funktion mit der eigentlich Frage in diesem Thread gar nichts zu tun hat. Aber vielleicht braucht man ja mal ein Edit, in dem man nur Zahlen eingeben, aber nicht wieder löschen kann.

Chewie 26. Aug 2004 15:02

Re: Assigned
 
Langsamer ist der Zugriff aus das Property nicht, da der Zugriff auf Properties bereits zur Kompilierzeit und nicht erst zur Laufzeit ausgewertet wird.

Muetze1 26. Aug 2004 15:18

Re: Assigned
 
Moin!

In wie fern zur Compilerzeit? Wie sollte ich es mir denn vorstellen wenn ich per RTTI eine Property suche und dann drauf zugreife? Erkläre mir das mal bitte genauer...

Ansonsten meinte ich langsamer in dem Sinne, da manche eine Methode hinter einer Property definieren und somit ist es langsamer als der direkte Zugriff auf die Variable. Und genauso meine ich in dem Zusammenhang das gefährliche, wenn es eine Lese-Methode für die Property gibt und man darin noch andere Dinge macht die dann zu einer Call-Schleife führen können oder andere böse Dinge.

MfG
Muetze1

Chewie 26. Aug 2004 15:45

Re: Assigned
 
Zitat:

Zitat von Muetze1
Moin!

In wie fern zur Compilerzeit? Wie sollte ich es mir denn vorstellen wenn ich per RTTI eine Property suche und dann drauf zugreife? Erkläre mir das mal bitte genauer...

Die RTTI werden auch nur bei published-Properties angelegt und sind imho primär ein Hilfsmittel, um Dinge wie den Objektinspektor zu ermöglichen.

Zitat:

Zitat von Muetze1
Ansonsten meinte ich langsamer in dem Sinne, da manche eine Methode hinter einer Property definieren und somit ist es langsamer als der direkte Zugriff auf die Variable. Und genauso meine ich in dem Zusammenhang das gefährliche, wenn es eine Lese-Methode für die Property gibt und man darin noch andere Dinge macht die dann zu einer Call-Schleife führen können oder andere böse Dinge.

MfG
Muetze1

Man sollte den Aufbau der Klasse schon kennen. Klar, man arbeitet ja auch selbst im Innern ;)
Sicherer ist es natürlich schon, das Feld direkt anzusprechen, aber wenn man dem typischen Styleguide folgt, spart man sich so ein Zeichen zu tippen ;)

Muetze1 26. Aug 2004 16:13

Re: Assigned
 
Moin!

Zitat:

Zitat von Chewie
Zitat:

Zitat von Muetze1
Moin!

In wie fern zur Compilerzeit? Wie sollte ich es mir denn vorstellen wenn ich per RTTI eine Property suche und dann drauf zugreife? Erkläre mir das mal bitte genauer...

Die RTTI werden auch nur bei published-Properties angelegt und sind imho primär ein Hilfsmittel, um Dinge wie den Objektinspektor zu ermöglichen.

Ok, ich meinte auch die Published Eigenschaften. Und nun erklär mir mal bitte deine Aussage mit dem Aufbauen des Codes zur Compilerzeit und sozusagen wegnehmen der Read/Write Routinen (so hatte ich es verstanden) und dem Zugriff auf selbige zur Runtime...

MfG
Muetze1

DP-Maintenance 12. Sep 2004 09:08

DP-Maintenance
 
Dieses Thema wurde von "sakura" von "Sonstige Fragen zu Delphi" nach "Object-Pascal / Delphi-Language" verschoben.

woki 12. Sep 2004 12:34

Re: Assigned
 
Zitat:

Zitat von Muetze1
Ok, ich meinte auch die Published Eigenschaften. Und nun erklär mir mal bitte deine Aussage mit dem Aufbauen des Codes zur Compilerzeit und sozusagen wegnehmen der Read/Write Routinen (so hatte ich es verstanden) und dem Zugriff auf selbige zur Runtime...

Nun, einfach mal mit logischem ÜBerlegen, und ohne dass ich den Sourcecode des Compilers überprüft häte, folgender hypothetischer Source:

Code:
AClass :TClass

private
  FProp :integer;
public
  prop :integer read Fprop;
end
Bei einem Zugriff auf prop weiß der Compiler, dass hier nichts weiter passiert, als dass direkt FProp zurückgeliefert wird, Lesezugriffe auf Prop und FProp sind also äquivalent, der Compiler kann das erkennen und entsprechend optimierten Code erzeugen, ohne gegen das Prinzip der Kapselung zu verstoßen, und ohne das der Entwickler Probleme bekommt wenn er später einmal den internen Aufbau seiner Klasse durch Einziehen eines Getters erweitert.

Wenn ich das im Vorübergehen so richtig verstanden habe, ist es ein ähnliches Prinzip, mit dem DotNet einige Performanceprobleme von Java beseitigt, oder wie A.H. sagt:
"Goog Idesas do not suddenly go away".

Ich denke, dass es auch innerhalb einer Klasse sinnvoll sein kann, auf eine property zuzugeifen, wenn klar ist, dass der Wert der property interessiert, auch wenn bei einer zukünftigen Weiterentwicklung, der reine Feldwert durch einen Getter ersetzt wird, oder das Auslesen / Schreiben Seiteneffekte haben soll. Die VCL bstätigt mich da.
Man sollte sich nur darüber bewußt sein, und welchen Preis man je nach Entwicklungssprache und Compiler/Interpreter Implementation bezahlen muß.

Grüsse
Woki

Chewie 12. Sep 2004 13:02

Re: Assigned
 
Zu beachten ist in der Hinsicht auch, dass die Sichtbarkeitsstufen nur vom Compiler ausgewertet werden. Im Compilat gibts zwischen pirvate, protected, public und published keine Unterschiede mehr (außer der Reihenfolge im Speicher).


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz