Operator
 
Декларирует или определяет перегруженный оператор.

Синтаксис

{ Type | Class | Union | Enum } typename
Declare Operator Cast () As datatype
Declare Operator @ () As datatype
Declare Operator assignment_op ( [ ByRef | ByVal ] rhs As datatype )
Declare Operator New ( size As UInteger ) As Any Ptr
Declare Operator New[] ( size As UInteger ) As Any Ptr
Declare Operator Delete ( buf As Any Ptr )
Declare Operator Delete[] ( buf As Any Ptr )
End { Type | Class | Union | Enum }

{ Type | Class | Union } typename
Declare Operator For ()
Declare Operator For ( [ ByRef | ByVal ] stp As typename )
Declare Operator Step ()
Declare Operator Step ( [ ByRef | ByVal ] stp As typename )
Declare Operator Next ( [ ByRef | ByVal ] cond As typename ) As Integer
Declare Operator Next ( [ ByRef | ByVal ] cond As typename, [ ByRef | ByVal ] stp As typename ) As Integer
End { Type | Class | Union }

Declare Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As datatype
Declare Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef | ByVal ] rhs As datatype ) As datatype

Operator typename.Cast () As datatype
Operator typename.@ () As datatype
Operator typename.assignment_op ( [ ByRef | ByVal ] rhs As datatype )
Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As datatype
Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef | ByVal ] rhs As datatype ) As datatype
Operator typename.New ( size as uinteger ) As Any Ptr
Operator typename.New[] ( size As UInteger ) As Any Ptr
Operator typename.Delete ( buf As Any Ptr )
Operator typename.Delete[] ( buf As Any Ptr )

Параметры

typename
Имя Type, Class, Union, или Enum.
assignment_op
let += -= *= &= /= \= mod= shl= shr= and= or= xor= imp= eqv= ^=
unary_op
- not * -> abs sgn fix frac int exp log sin asin cos acos tan atn
binary_op
+ - * & / \ mod shl shr and or xor imp eqv ^ = <> < > <= >=

Описание

Встроенные операторы, такие как =, +, и cast имеют предопределенное поведение при использовании в выражениях. Эти операторы могут быть перегружены, чтобы делать что-то помимо стандартных операций, когда по крайней мере один из аргументов для оператора Type, Class, Enum, или Union тип данных.

Операторы являются просто функциями. Оператор '+' имеет функциональность как Function Plus( A as DataType, B as DataType ) as DataType. Смотрите Перегрузка операторов для получения дополнительной информации. Операторы могут быть перегружены принимать различные типы данных в качестве параметров. Только оператор Cast может быть перегружен для возвращения различных типов.

Нестатический оператор-элемент объявляются внутри Type или Class. Глобальные операторы объявляются вне. Все определения оператора (тело процедуры) должны отображаться за пределами.

Let, Cast, и другие операторы присваивания должны быть объявлены внутри Type или Class. Они передаются со скрытым параметром This и имеют такой же тип, как возвращаемые данные Type или Class в котором они были объявлены.

Унарные операторы должны быть объявлены вне Type, Class, или Enum и иметь явно объявленный тип данных возврата. Унарные операторы могут быть перегружены, чтобы возвращать любой действительный тип данных, за исключением Оператора -> (Указатель на доступ к элементу) который должен возвращать тип данных Type или Class.

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

Let относится к операторам присваивания, как в LET a=b. Ключевое слово Let опускается в общей практике и не допускается в диалекте -lang fb. Однако, Let() может использоваться для присваивания полям определяемого пользователем типа нескольких переменных.

Смотрите For, Step, и Next для получения дополнительной информации о перегрузке заявления For..Next для определяемых пользователем типов.

New, New[], Delete, и Delete[] операторы-элементы всегда являются статическими, даже если явно не указано (Ключевое слово Static является ненужным, но допускается).

Пример

'' operator1.bas

Type Vector2D
  As Single x, y

  '' Возвращает строку, содержащую данные vector.
  Declare Operator Cast() As String

  '' Умножение вектора на скаляр.
  Declare Operator *= ( ByVal rhs As Single )
End Type

'' Разрешить два вектора, чтобы иметь возможность добавлять их вместе.
Declare Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D

'' Возвращает модуль (Single) vector с помощью перегруженного оператора abs().
Declare Operator Abs (  ByRef rhs As Vector2D ) As Single

Operator Vector2D.cast () As String
  Return "(" + Str(x) + ", " + Str(y) + ")"
End Operator

Operator Vector2D.*= ( ByVal rhs As Single )
  This.x *= rhs
  This.y *= rhs
End Operator

Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D
  Return Type<Vector2D>( lhs.x + rhs.x, lhs.y + rhs.y )
End Operator

Operator Abs ( ByRef rhs As Vector2D ) As Single
  Return Sqr( rhs.x * rhs.x + rhs.y * rhs.y )
End Operator

Dim a As Vector2D = Type<Vector2D>( 1.2, 3.4 )
Dim b As Vector2D = Type<Vector2D>( 8.9, 6.7 )
Dim c As Vector2D = Type<Vector2D>( 4.3, 5.6 )

Print "a = "; a, "abs(a) ="; Abs( a )
Print "b = "; b, "abs(b) ="; Abs( b )
Print "a + b = "; a + b, "abs(a+b) ="; Abs( a + b )
Print "c = "; c, "abs(c) ="; Abs( c )
Print "'c *= 3'"
c *= 3
Print "c = "; c, "abs(c) ="; Abs( c )

Выравнивание распределения памяти:
    • с помощью перегруженных операторов элементов "New" и "Delete", любой созданный объект пользователя выравнивается до кратного "ВЫРАВНИВАНИЯ" байт (256 байт в этом примере),
    • Настоящий указатель выделенной памяти сохраняется чуть выше пользовательского указателя, в блоке заполнения.
'' operator2.bas

Const ALIGN = 256

Type UDT
  Dim As Byte a(0 To 10 * 1024 * 1024 - 1) '' 10 мегабайт фиксированный массив
  Declare Operator New (ByVal size As UInteger) As Any Ptr
  Declare Operator Delete (ByVal buffer As Any Ptr)
  Declare Constructor ()
  Declare Destructor ()
End Type

Operator UDT.New (ByVal size As UInteger) As Any Ptr
  Print "  Overloaded New operator, with parameter size = &h" & Hex(size)
  Dim pOrig As Any Ptr = CAllocate(ALIGN-1 + SizeOf(UDT Ptr) + size)
  Dim pMin As Any Ptr = pOrig + SizeOf(UDT Ptr) 
  Dim p As Any Ptr = pMin + ALIGN-1 - (CULng(pMin + ALIGN-1) Mod ALIGN)
  Cast(Any Ptr Ptr, p)[-1] = pOrig
  Operator = p
  Print "  real pointer = &h" & Hex(pOrig), "return pointer = &h" & Hex(p)
End Operator

Operator UDT.Delete (ByVal buffer As Any Ptr)
  Print "  Overloaded Delete operator, with parameter buffer = &h" & Hex(buffer)
  Dim pOrig As Any Ptr = Cast(Any Ptr Ptr, buffer)[-1]
  Deallocate(pOrig)
  Print "  real pointer = &h" & Hex(pOrig)
End Operator

Constructor UDT ()
  Print "  Constructor, @This = &h" & Hex(@This)
End Constructor

Destructor UDT ()
  Print "  Destructor, @This = &h" & Hex(@This)
End Destructor

Print "'Dim As UDT Ptr p = New UDT'"
Dim As UDT Ptr p = New UDT

Print "  p = &h" & Hex(p)

Print "'Delete p'"
Delete p

Вывод:
'Dim As UDT Ptr p = New UDT'
  Overloaded New operator, with parameter size = &hA00000
  real pointer = &h420020   return pointer = &h420100
  Constructor, @This = &h420100
  p = &h420100
'Delete p'
  Destructor, @This = &h420100
  Overloaded Delete operator, with parameter buffer = &h420100
  real pointer = &h420020
Различия диалектов

  • Доступно только в диалекте -lang fb.

См. также