Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Type als Objekt - Das UDT-Tutorial Teil 2

von RedakteurMODSeite 3 von 3

Übergabe von Objekten an Funktionen ByVal

Der Grundgedanke von 'Deep' und 'Shallow Copies' trifft auch auf die BefehlsreferenzeintragByVal Übergabe eines Objekts an eine Funktion zu. Wird eine Referenz zu einem Objekt (BefehlsreferenzeintragByRef) übergeben, kann das Objekt geändert werden und diese Änderungen bleiben erhalten, aber die Übergabe geht auch ByVal, d.h. das Objekt kann geändert werden, ohne dass diese Änderungen außerhalb der Funktion erhalten bleiben. Wird ein Objekt einer Funktion ByVal übergeben, wird eine neue Kopie erstellt und wenn das Objekt einen Copy Constructor hat, wird dieser ausgeführt, wenn nicht, wird die versteckte 'Shallow Copy' benutzt. Ist die Funktion dann beendet, wird der Destructor des Objekts ausgeführt.


New/Delete

BefehlsreferenzeintragNew und BefehlsreferenzeintragDelete sind spezielle Operatoren zum dynamischen Zuweisen von Speicher und zur Freigabe. Da sie mit dynamischem Speicher arbeiten, werden sie mit Pointern benutzt. In allen Beispielen haben wir bis jetzt einfach BefehlsreferenzeintragDim zum Erstellen unserer Objekte verwendet. Damit werden sie im Stack-Bereich des Arbeitsspeichers erstellt, aber mit New können wir sie dynamisch erzeugen. Das kann mehr Flexibilität geben, so wie die Verwendung von BefehlsreferenzeintragAllocate/BefehlsreferenzeintragDeAllocate mit normalem Speicher. Weiterhin ist es wichtig zu wissen, dass nach der Verwendung von New nicht geprüft werden muss, ob der Pointer NULL ist, wie man es vielleicht bei Allocate tun müsste. Geht New schief, ruft das eine Exception hervor, die dann das Programm beendet. In neueren Versionen von FreeBASIC, wird es wahrscheinlich eine Art 'Try..Catch'-Mechanismus geben, wie er etwa in Java vorkommt, damit solche Exceptions besser abgefangen werden können, aber zum jetzigen Zeitpunkt (Version 0.21.1) ist das noch nicht eingebaut.

Es gibt zwei verschiedene Arten von New/Delete. Die erste Art erzeugt einfach ein einziges Element oder Objekt, z.B.:

Dim As Integer Ptr foo = New Integer

*foo = 1
Print *foo

Delete foo

Es wird ein neuer BefehlsreferenzeintragInteger erzeugt und dann mittels Delete wieder freigegeben. Nicht vergessen: Es werden BefehlsreferenzeintragPtr verwendet, denn es handelt sich um dynamischen Speicher. Für einfache BefehlsreferenzeintragDatentypen kann auch ein Standardwert mit Klammern hinter dem Datentyp angegeben werden, z.B.:

Dim As Integer Ptr foo = New Integer(42)

Print *foo

Delete foo

Das geht auch bei UDT's:

Type foo
  x As Integer
  y As Integer
End Type

Dim As foo Ptr bar = New foo(1, 2)

Print bar->x, bar->y

Delete bar

Diese Initialisierung funktioniert nicht bei komplexeren Types (mit Constructoren/Destructoren etc.), ein sinvolles Feature ist jedoch, dass bei New/Delete mit Objekten auch der Constructor und Destructor aufgerufen wird, siehe folgendes Beispiel:

Type foo
  Declare Constructor()
  Declare Destructor()

  x As Integer
  y As Integer
End Type

Constructor foo()
  Print "ctor"
End Constructor

Destructor foo()
  Print "dtor"
End Destructor

Dim As foo Ptr bar = New foo

Delete bar

Man wird sehen, dass der Constructor und Destructor des Objekts augerufen werden.

Die zweite Art von New/Delete ist zum Erstellen von BefehlsreferenzeintragArrays. Hierbei wird die Anzahl der Elemente nach dem Datentyp in eckigen Klammern '[]' angegeben. Wird diese Array-Version verwendet, muss auch 'Delete[]' anstatt von 'Delete' genommen werden, so dass FreeBASIC weiß, dass ein Array gelöscht wird.
Ein einfaches Beispiel mit einem Integer-Typ:

Dim As Integer Ptr foo = New Integer[20]

foo[1] = 1
Print foo[1]

Delete[] foo

Es erzeugt ein dynamisches Array mit 20 Integer Elementen (Index 0 bis 19). Es sollte beachtet werden, dass dies sich von Allocate unterscheidet, dass die Anzahl der Bytes als Argument benötigt; mit New, sollte die Anzahl der Elemente angegeben werden. Die Array-Methode geht genauso für Objekte:

Type foo
  Declare Constructor()
  Declare Destructor()

  x As Integer
  y As Integer
End Type

Constructor foo()
  Print "ctor"
End Constructor

Destructor foo()
  Print "dtor"
End Destructor

Dim As foo Ptr bar = New foo[3]

Delete[] bar

Wird dieser Code ausgeführt, werden drei Constructor/Destructor-Paare ausgeführt, da wir ein Array mit drei Instanzen von foo erstellt haben.

Es darf nie vergessen werden, Delete bzw. Delete[] für jede Speicherzuweisung mit New bzw. New[] aufzurufen, sonst entsteht ein Speicherleck, so wie auch DeAllocate aufgerufen werden muss, wenn mit Allocate Speicher zugewiesen wurde.


Schlussbemerkung
------------------------

Damit wären wir auch am Ende des zweiten Teils. Zum Abschluss noch etwas zum Tutorial selbst:

Das Original ist auf englisch und befindet sich bei den Externer Link!Tutorials der Externer Link!FreeBASIC Homepage (Externer Link!Teil 1, Externer Link!Teil 2). Verfasst wurde es von YetiFoot. Es enthält im zweiten Teil drei weitere Punkte, die allerdings interne Abläufe beschreiben und bei der Verwendung von Types als Objekt keine Relevanz haben. Übersetzt wurde das Tutorial von ytwinky, einem der Gründungsmitglieder der deutschen FreeBASIC Community.
Ich selbst habe die Übersetzung von ytwinky aktualisiert, leicht umgeformt und zusätzliche Informationen und Links eingebracht, die beim Verständnis und weiterem Interesse hilfreich sein könnten.


siehe auch:
BefehlsreferenzeintragNew
BefehlsreferenzeintragDelete

 

Gehe zu Seite Gehe zu Seite  1  2  3  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 06.09.2010 von RedakteurMOD angelegt.
  • Die aktuellste Version wurde am 28.08.2011 von RedakteurMOD gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen