Constructor
 
Вызывается автоматически, когда создается класс или определяемый пользователем тип

Синтаксис

Type typename
Declare Constructor ( )
Declare Constructor ( [ ByRef | ByVal ] parameter As datatype [ = default ] [, ... ] )
End Type

Constructor typename ( [ parameters ] )
statements
End Constructor

Параметры

typename
имя Type или Class

Описание

Метод Constructor вызывается, когда создается определяемый пользователем Type или Class.

typename - это имя типа, для которого метод Constructor декларируется и определяется. Разрешение имен для typename следует тем же правилам, что и процедуры при использовании в Namespace.

Может существовать более одного конструктора для типа или класса. Точный вызов метода конструктора зависит от сигнатуры parameter , когда переменная инициализируется. Более чем один parameter может существовать в декларации метода конструктора.

В метод конструктора передается скрытый параметр This , имеющий тот же тип, что и typename. This необязательно использовать для доступ к полям Type или Class , которые могут быть инициализированы в методе Constructor.

Цепочка из конструкторов во вложенных типах поддерживается. Любые поля, которые имеют свой собственный конструктор по умолчанию вызываются первые.

Конструкторы вызываются при объявлении глобальных или локальных статических экземпляров typename и при выделении памяти для typename динамически, используя оператор New. Смотрите примеры ниже для различного синтаксиса конструктора.

Конструктор копирования - специальный конструктор, который инициализирует новый объект из существующего объекта. Существуют три основных случая, когда конструктор копирования вызывается: при создании экземпляра одного объекта и инициализации его с другим объектом (в одной команде), при передаче объекта по значению, когда объект возвращается из функции по значению (с помощью Return x ).
Примечание: Когда объект возвращается из функции по значению, но с помощью Function = x (или function_identifier = x) , конструктор вызывается один раз первым, а затем оператор Let (присваивание) для каждого задания.
Конструктор копирования должен быть определен, если малый неявный конструктор копирования не достаточен. Это происходит в случаях, когда объект управляет динамично выделенной памятью или другими ресурсами, которые должны быть особенно построены или скопированы (например, если элемент-указатель укажет на динамично выделенную память, то неявный конструктор копирования просто создаст неявное построение указателя и копию имеющую значение вместо выделенной памяти , а затем выполняет копирование данных).
Примечание: Даже если определен явный конструктор по умолчанию, он никогда не вызывает неявный конструктор копирования.

Конструктор также можно вызвать непосредственно из экземпляра typename как другие методы-элементы (Sub) и с тем же синтаксисом, т.е. используя оператор доступа к элементу, например obj.Constructor(parameters). Деструктор не вызывается, и старое состояние объекта - если таковое имеется - перезаписывается без каких-либо разрушений своих старых элементов, которые могут вызвать утечку памяти и ресурсов.

Пример

Пример простого конструктора для начинающих.
Type MyObj
  Foo As Integer Ptr
  
    '' Конструктор создает наш integer, и устанавливает его значение.
  Declare Constructor( ByVal DefVal As Integer = 0 )
    '' Удаляет наш integer при удалении объекта.
  Declare Destructor()
End Type

Constructor MyObj( ByVal DefVal As Integer = 0 )
  Print "Creating a new integer in MyObj!"
  Print "The Integer will have the value of: " & DefVal
  Print ""
  
    '' Создаем указатель и установим его значение из единствено-передаваемого
    '' конструктора.
  This.Foo = New Integer
  *This.Foo = DefVal
End Constructor

Destructor MyObj()
  Print "Deleting our Integer in MyObj!"
  Print ""
  
    '' Удалим указатель, который мы создали в MyObj.
  Delete This.Foo
  This.Foo = 0
End Destructor


Scope
    '' Создадим объект типа MyObj
    '' Отправим значение '10' в конструктор
  Dim As MyObj Bar = 10
  
    '' Смотрим, если integer создан.  Печатаем его значение.
  Print "The Value of our integer is: " & *Bar.Foo
  Print ""
  
  Sleep
End Scope
  '' Мы только что вышли из области видимости.  Деструктор должен вызываться сейчас
  '' потому что наш объект удаляется.
Sleep

Более сложный пример построения, показана перегрузка конструкторов среди прочего.
Type sample

  _text As String

  Declare Constructor ()
  Declare Constructor ( a As Integer )
  Declare Constructor ( a As Single  ) 
  Declare Constructor ( a As String, b As Byte ) 

  Declare Operator Cast () As String

End Type

Constructor sample ()
  Print "constructor sample ()"
  Print
  this._text = "Empty"
End Constructor

Constructor sample ( a As Integer )
  Print "constructor sample ( a as integer )"
  Print "  a = "; a
  Print
  this._text = Str(a)
End Constructor

Constructor sample ( a As Single )
  Print "constructor sample ( a as single )"
  Print "  a = "; a
  Print
  this._text = Str(a)
End Constructor

Constructor sample ( a As String, b As Byte )
  Print "constructor sample ( a as string, b as byte )"
  Print "  a = "; a
  Print "  b = "; b
  Print
  this._text = Str(a) + "," + Str(b)
End Constructor

Operator sample.cast () As String
  Return this._text
End Operator

Print "Creating x1"
Dim x1 As sample

Print "Creating x2"
Dim x2 As sample = 1

Print "Creating x3"
Dim x3 As sample = 99.9

Print "Creating x4"
Dim x4 As sample = sample( "aaa", 1 )

Print "Values:"
Print "  x1 = "; x1
Print "  x2 = "; x2
Print "  x3 = "; x3
Print "  x4 = "; x4

Пример конструктора копирования.
Type UDT
  Dim As String Ptr p                     ''указатель на строку
  Declare Constructor ()                  ''конструктор по умолчанию
  Declare Constructor (ByRef rhs As UDT)  ''конструктор копирования
  Declare Destructor ()                   ''деструктор
End Type

Constructor UDT ()
  This.p = CAllocate(1, SizeOf(String))
End Constructor

Constructor UDT (ByRef rhs As UDT)
  This.p = CAllocate(1, SizeOf(String))
  *This.p = *rhs.p
End Constructor

Destructor UDT ()
  *This.p = ""
  Deallocate This.p
End Destructor


Dim As UDT u0
*u0.p = "copy constructor exists"
Dim As UDT u = u0
*u0.p = ""  '' чтобы проверить независимость результата копирования с объектом копирования
Print *u.p
Sleep

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

  • Объектно-связанные функции поддерживаются только с опцией -lang fb

Отличия от QB

  • Новое в FreeBASIC

См. также