Referenz - TYPE (UDT)
Syntax A:
TYPE TypenName [EXTENDS Mutterklasse] [FIELD = {1|2|4}]
  [PRIVATE:|PUBLIC:|PROTECTED:]
  variable[(Arraygrenzen)] AS Datentyp [= Wert]
  variable : bits AS Datentyp [= Wert]
  AS Datentyp variable [(Arraygrenzen)] [= Wert], ...
  AS Datentyp variable : bits [= Wert]
  DECLARE {SUB|FUNCTION|CONSTRUCTOR|DESTRUCTOR|PROPERTY|OPERATOR} ...
  ...
END TYPE
Syntax B:
TYPE TypenName AS Datentyp
Typ: Anweisung
Kategorie: Klassen
TYPE wird verwendet, um UDTs (user defined types, also benutzerdefinierte Datentypen) zu erstellen, die mehrere Variablen/Arrays enthalten können.
- 'variable' ist der Bezeichner einer Variablen, die im UDT verwendet wird. Sie wird als Attribut bezeichnet. Die Syntax zur Definition von Attributen ist ähnlich wie bei 
DIM. - 'Datentyp' ist der Typ, den das Attribut besitzen soll. Jedes Attribut kann seinen eigenen Datentyp besitzen. Auch 
Arrays, 
Strings fester und variabler Länge, 
Pointer (Zeiger) und andere UDTs sind erlaubt. - 'bits' wird zusammen mit 
Bitfeldern eingesetzt. Die Definition von Bitfeldern wird weiter unten erläutert. - UDTs können Methoden enthalten. Diese werden innerhalb der Typendefinition deklariert. Es handelt sich hierbei um 
Prozeduren, die an den UDT gebunden sind. Siehe auch 
SUB und 
FUNCTION. - Für die weiteren Deklarationsmöglichkeiten siehe 
CONSTRUCTOR / 
DESTRUCTOR, 
PROPERTY und 
OPERATOR. 
EXTENDS kann verwendet werden, um den eigenen Datentypen die Attribute und Methoden eines anderen UDTs erben zu lassen.- FIELD bestimmt, auf welche Größe das Feld ausgedehnt werden soll ("Padding"). Siehe 
FIELD für weitere Informationen. 
Ein mit TYPE erstellter Datentyp kann einer Variable mit 
DIM, 
REDIM, 
COMMON oder 
STATIC (Anweisung) zugewiesen werden. Auf die einzelnen Attribute wird dann über die Syntax Variable.Attribut zugegriffen (siehe auch 
WITH, 
TYPE (Funktion)).
Dynamische Arrays können als Attribute nur verwendet werden, wenn die Anzahl der Dimensionen festgelegt wird. Dazu wird anstelle der Arraygrenzen das Schlüsselwort ANY verwendet.
Beispiel 1:
TYPE clr
  AS UBYTE red, green, blue
END TYPE
TYPE AnotherUDT
  IntVal           AS INTEGER
  fStrVal          AS STRING * 7
  vStrVal          AS STRING
  Array(5)         AS clr
  DynArr(ANY, ANY) AS INTEGER
  UdtPtr           AS clr PTR
END TYPE
DIM a AS clr
DIM b AS AnotherUDT
a.red = 255
a.green = 128
a.blue = 64
PRINT a.red, a.green, a.blue
PRINT
b.IntVal  = 10023
b.fStrVal = "abcdefg"
b.vStrVal = "abcdefghijklmnopqDrstuvwxyz"
b.Array(0).green = 255
REDIM b.DynArr(4, 5)
b.UdtPtr  = @a
PRINT b.IntVal
PRINT b.fStrVal
PRINT b.vStrVal
PRINT b.Array(0).green
PRINT UBOUND(b.DynArr,1)
PRINT b.UdtPtr->blue
SLEEP 
Bitfelder
Wollen Sie eine Reihe von Ganzzahlen in einem UDT speichern, die in einem relativ kleinen Wertebereich liegen, können Sie das über ein Bitfeld erreichen. Siehe dazu 
Bitfelder.
TYPE BitFeldName [FIELD = {1|2|4}]
  BitName : Bits AS Datentyp
  ' oder alternativ
  AS Datentyp BitName : Bits
   ...
END TYPE
- 'BitName' ist dabei der Bezeichner, über den das Attribut angesprochen werden kann.
 - 'Bits' ist eine Ganzzahl, die angibt, wie viele Bits für dieses Attribut verwendet werden sollen.
 - 'Datentyp' muss einer der Datentypen (U)BYTE, (U)SHORT, (U)INTEGER oder (U)LONG sein. Alle anderen Datentypen führen zu Fehlermeldungen. Der Datentyp muss mindestens 'Bits' Bit groß sein.
 - Für das Padding gelten dieselben Regeln wie bei normalen Feldern.
 
Beispiel 2: Checkbox-Verwaltung mit Bitfeldern:
TYPE CheckBoxenTypeD
  CB1 : 1 AS INTEGER
  CB2 : 1 AS INTEGER
  CB3 : 1 AS INTEGER
END TYPE
DIM CheckBoxen AS CheckBoxenType
' Status setzen:
CheckBoxen.CB1 = 1 ' aktiv
CheckBoxen.CB2 = 0 ' nicht aktiv
CheckBoxen.CB3 = 1 ' aktiv
' ... Programmcode ...
' Status abfragen:
IF CheckBoxen.CB1 THEN '...
IF CheckBoxen.CB2 THEN '...
IF CheckBoxen.CB3 THEN '... 
TYPE zur Festlegung eines Alias
Syntax B erlaubt es, eine Variable direkt wie einen eingebauten Datentypen zu verwenden:
TYPE meinDatentyp AS andererDatentyp
Der Vorteil dieser Methode ist, dass man bei einer späteren Änderung den Datentypen nur an einer Stelle ändern muss, statt an jeder Stelle, an welcher der Datentyp verwendet wird.
FreeBASIC erlaubt für diese Syntaxform neben den allgemeinen Datentypen auch Pointer auf Prozeduren (Callbacks). Dies hat die Vorteile, dass einerseits die Deklaration verkürzt wird, was Schreibaufwand erspDaren kann und andererseits, im Gegensatz zur normalen Deklaration, auch Pointer auf Callbackfunktionen ermöglicht werden:
' Beispielfunktionen
Function testAufruf() As Integer
  Return 1
End Function
Function testAufrufPointer() As Integer Ptr
  Return Cast(Integer Ptr, 2)
End Function
' Callbackfunktionen
Dim func As Function() As Integer
Dim pointerFunc As Function() As Integer Ptr
' Pointer für Callbackfunktionen
Type pointerFunc_Type As Function() As Integer
Dim pointerPointerFunc As pointerFunc_Type Ptr
' Funktionszuweisungen
func = @testAufruf 'Callback auf die erste Funktion
pointerFunc = @testAufrufPointer 'Callback auf die zweite Funktion
pointerPointerFunc = @func 'Pointer auf das Callback der ersten Funktion
Print "Funktionsadressen:", func, pointerFunc, pointerPointerFunc
Print "Funktionsaufrufe:", func(),D pointerFunc(), *pointerPointerFunc()
Sleep 
Objektorientierte Programmierung
FreeBASIC bietet objektorientierte Ansätze, die beispielsweise Methoden, 
Konstruktoren und 
Destruktoren in UDTs erlauben. Eine ausführliche Anleitung dazu findet sich im UDT-Tutorial.
Beispiel 3 für objektorientierte Programmierung:
' Vektorklasse
Type Vector
  W as Integer
  H as Integer
  Declare Constructor (nW as Integer, nH as Integer)
End Type
Constructor Vector (nW as Integer, nH as Integer)
  W = nW
  H = nH
End Constructor
' Klasse zur Erstellung eines Objekts
Type AObject
  Private:
    X as Integer
    Y as Integer
    Movement as Vector Pointer
  Public:
    ' öffentliche Methoden inklusive eines Konstruktors und eines Destruktors
    Declare Constructor (nX as Integer, nY as Integer)
    Declare Destructor ()
    Declare Sub SetMotion (Motion as Vector Pointer)
    Declare Sub Move ()
    Declare Property GetX as Integer
End Type
' Initialwerte setzen
Constructor AObject (nX as Integer, nY as Integer)
  X = nX
  Y = nY
End Constructor
' allozierten Speicher freigeben
Destructor AObject ()D
  Delete Movement
End Destructor
' Bewegungsvektor setzen
Sub AObject.SetMotion (Motion as Vector Pointer)
  Movement = Motion
End Sub
' das Objekt anhand seines Bewegungsvektors bewegen
Sub AObject.Move ()
  X += Movement->W
  Y += Movement->H
End Sub
' Rückgabe von X, welches sonst nicht zugänglich wäre
Property AObject.GetX as Integer
  Return X
End Property
' Hauptprogramm
' eine neue Instanz von 'AObject' an den Koordinaten 100, 100 erstellen
Dim Player as AObject = Type<AObject>(100, 100)
' ein neues Vektorobjekt dynamisch allozieren
' und dessen Position um 10 nach links und 5 nach unten verschieben
Player.SetMotion(new Vector (-10, 5))
' die Position von 'Player' aktualisieren
Player.Move()
' den neuen Wert von X (90) anzeigen
Print Player.GetX
' Weil 'Player' eine lokale Variable ist, wird sein Destruktor
' am Ende des Scopes automatisch aufgerufen
' vor Programmende auf Tastendruck warten
Sleep
Alle UDTs besitzen Standard-Konstruktoren und -Destruktoren, falls keine anderen definiert wurden, die diese überschreiben. Sie können jederzeit explizit aufgerufen werden. Dies gilt allerdings auch für selbsterstellte Konstruktoren und Destruktoren.
Type myType
  x As Integer
End Type
Dim As myType Ptr myVar = New myType
myVar->Constructor
myVar->Destructor
Delete myVar
Sleep
Unterschiede zu QB:
- In FreeBASIC besitzen Strings fester Länge im Gegensatz zu QB ein zusätzliches Zeichen am Ende, wodurch UDTs mit diesen Strings nicht kompatibel zu QB sind, wenn sie bei Dateioperationen verwendet werden.
 - FreeBASIC unterstützt auch Bitfelder.
 
Plattformbedingte Unterschiede:
- Das Standardpadding unter Linux und DOS ist 4 Byte.
 - Das Standardpadding unter Windows ist 8 Byte.
 
Unterschiede zu früheren Versionen von FreeBASIC:
- Dynamische Arrays in UDTs sind seit FreeBASIC v1.00 erlaubt.
 - Bitfelder existieren seit FreeBASIC v0.13.
 - Methoden in UDTs existieren seit v0.17.
 
Unterschiede unter den FB-Dialektformen:
- Methoden in UDTs sind nur in der Dialektform 
-lang fb verfügbar. - Das Standardpadding in -lang fb und -lang fblite hängt von der Plattform ab, während in -lang qb kein Padding durchgeführt wird.
 
Siehe auch:
TYPE (Funktion), 
TYPE (Forward Referencing), 
DIM, 
OFFSETOF, 
FIELD, 
WITH, 
OPERATOR, 
CONSTRUCTOR, 
DESTRUCTOR, 
PROPERTY, 
OBJECT, 
EXTENDS, 
Bitfelder, 
Datentypen und Deklarationen, 
Objektorientierung
| Zusätzliche Informationen und Funktionen | ||||
|---|---|---|---|---|
				
  | 
		||||



			FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!
 Versionen