Type
 
Декларирует определяемый пользователем тип.

Синтаксис

Type typename
fieldname1 As DataType
fieldname2 As DataType
As DataType fieldname3, fieldname4
...
End Type

Type typename [Extends base_typename] [Field = alignment]
[Private:|Public:|Protected:]

Declare Sub|Function|Constructor|Destructor|Property|Operator ...
Static variablename As DataType

fieldname As DataType [= initializer]
fieldname(array dimensions) As DataType [= initializer]
fieldname : bits As DataType [= initializer]

As DataType fieldname [= initializer], ...
As DataType fieldname(array dimensions) [= initializer], ...
As DataType fieldname : bits [= initializer], ...

Union
fieldname As DataType
Type
fieldname As DataType
...
End Type
...
End Union

...
End Type

Описание

Type используется для объявления пользовательских типов данных, содержащие одно или несколько полей данных, в том числе целые типы, типы с плавающей точкой, массивы фиксированного размера, строки, битовые поля и другие безымянные пользовательские типы или union(ы).

Типы поддерживают различные функциональности, связанные с объектно-ориентированным программированием:
    • Наследование с помощью ключевого слова Extends
    • Процедуры-элементы, такие как Subs или Functions
    • Процедуры-элементы с особым смысловым значением, такие как Constructors или Destructor
    • Спецификаторы контроля доступа полей: Public:, Private:, Protected:

Разметка памяти
Типы располагают свои поля последовательно в памяти, используя нативное выравнивание и правила заполнения (описано на странице Field). Особое внимание должно приниматься при использовании типов для файлового ввода-вывода или взаимодействия с другими программами или языками программирования, в случае, если выравнивание и правила отступов отличаются. Необязательный спецификатор Field = number  может использоваться для изменения поведения на стороне FreeBASIC.

Динамические данные
Типы могут содержать динамические строки, но обратите внимание, что тип будет содержать дескриптор структуры String, а не строковые данные, которые динамически выделяются после создания типа и могут быть переменной длины, таким образом, строковые данные не могут быть вставлены в тип. Из-за этого сохранение такого типа в файл будет записывать дескриптор строки, а не фактические данные строки. Для того, чтобы внедрить строки в типы напрямую, необходимо использовать строки фиксированной длины. Аналогично при сохранении динамических данных вручную с помощью указателей в пределах типа, они обычно не имеет смысла для сохранения типа файла, потому что будет записываться в файл адрес, хранящийся в поле указателя, а не фактическую память, на которую он указывает. Адреса являются значимыми для конкретного процесса , хотя и не могут совместно использоваться таким образом.

Специальное примечание для строк фиксированной длины
В настоящее время поля строк фиксированной длины String * N  имеют дополнительный нулевой завершающий символ на их конце, для совместимости с C строками, что делает их несовместимыми с QB строками внутри типов, потому что они на самом деле используют N + 1 байт, а не просто N байт. Можно обойти это, объявив поле так: As String * (N-1), хотя это возможно не будет работать в будущих версиях, если нулевой завершающий символ будет удален. Другой альтернативой является использование массива Byte или UByte с надлежащим размером.

Замечание
Вложенные безымянные типы или Union(ы) не могут иметь функций-элементов.

Пример

Это пример типа QB-стиля, не включающий процедурные определения
Type clr
    red As UByte
    green As UByte
    blue As UByte
End Type

Dim c As clr
c.red = 255
c.green = 128
c.blue = 64


А это пример типа, работающий в качестве объекта:
'' Пример, показывающий проблемы с фиксированной длиной строковых полей в определяемых пользователем типах
'' Предположим, что мы прочитали заголовок GIF из файла
''                        сигнатура      ширина        высота
Dim As ZString*(10+1) z => "GIF89a" + MKShort(10) + MKShort(11)

Print "Using fixed-length string"

Type hdr1 Field = 1
   As String*(6-1) sig /' Мы должны уменьшить строку на 1 символ
                     '  чтобы избежать смещений '/
   As UShort wid, hei
End Type

Dim As hdr1 Ptr h1 = CPtr(hdr1 Ptr, @z)
Print h1->sig, h1->wid, h1->hei '' Печатаем GIF89 (пропускает символ!)  10  11

'' Мы можем сделать сравнение только с 5 видимыми символами и создания временной строки с LEFT

If Left(h1->sig, 5) = "GIF89" Then Print "ok" Else Print "error"


'' Использование массива UBYTE, нуждается во вспомогательной функции для преобразования его в строку
Function ub2str( ub() As UByte ) As String
    Dim As String res = Space(UBound(ub) - LBound(ub) + 1)
    For i As Integer = LBound(ub) To UBound(ub)
        res[i - LBound(ub)] = ub(i)
    Next
    Function = res
End Function


Print
Print "Using an array of ubytes"

Type hdr2 Field = 1
   sig(0 To 6-1) As UByte '' 6 измерений
   As UShort wid, hei
End Type

Dim As hdr2 Ptr h2 = CPtr(hdr2 Ptr, @z)
'' Просмотр и сравнение верно, но требуется преобразование в строку

Print ub2str(h2->sig()), h2->wid, h2->hei '' Печатается GIF89a  10  11 (верно)
If ub2str(h2->sig()) = "GIF89a" Then Print "ok" Else Print "error" '' Печатает ok


Различия платформ

  • По умолчанию Field параметр выравнивания составляет 4 байта для DOS и Linux.
  • По умолчанию Field параметр выравнивания составляет 8 байт для ОС Windows (Эта разница в отношении 4 байта относится только к элементам Longint и Double).

Различия диалектов

  • Объектные особенности, связанные, например, с функциями, объявленными внутри блоков Type поддерживаются только в диалекте -lang fb , начиная с версии 0.17b
  • В диалектах -lang fb и -lang fblite , по умолчанию Field параметр выравнивания зависит от целевой платформы.
  • С диалектом -lang qb поля выровнены по границе байта по умолчанию, если не указано иное.
  • Чтобы установить выравнивание байт используйте FIELD=1.

Отличия от QB

  • В настоящее время, строки фиксированной длины имеют дополнительный, резервный символ на конце, и это означает, что они занимают больше одного байта, чем в QB. По этой причине, пользовательские типы, которые их используют, не совместимы с QB при использовании для файлов ввода/вывода

См. также