Operator
Declares or defines an overloaded operator.
Syntax
`
{ Type | Class | Union | Enum } typename
Declare Operator Cast () As datatype
Declare Operator @ () As datatype Ptr
Declare Operator assignment_op ( [ ByRef | ByVal ] rhs As datatype )
Declare Operator [] ( index As datatype ) [ ByRef ] 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 Ptr
Operator typename.assignment_op ( [ ByRef | ByVal ] rhs As datatype )
Operator [] ( index As datatype ) [ ByRef ] 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 )
`
Parameters
`typename`
Name of the `Type`, `Class`, `Union`, or `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 len`
`binary_op`
`+ - * & / \ mod shl shr and or xor imp eqv ^ = <> < > <= >=`
Description
The built in operators like `=`, `+`, and `cast` have predefined behaviors when used in expressions. These operators can be overloaded to do something other than predefined operations when at least one of the arguments to the operator is a `Type`, `Class`, `Enum`, or `Union` data type.
Operators are just functions. The operator '+' has functionality like `Function Plus( A as DataType, B as DataType ) as DataType`. See Operator Overloading for more information. Operators can be overloaded to accept different data types as parameters. Only the `Cast` Operator can be overloaded to return different types.
Non-static operator members are declared inside the `Type` or `Class`. Global operators are declared outside. All operator definitions (procedure bodies) must appear outside.
`Let`, `Cast`, and other assignment operators must be declared inside the `Type` or `Class`. They are passed a hidden `This` parameter and have a return data type same as the `Type` or `Class` they are declared in.
Unary operators must be declared outside the `Type`, `Class`, or `Enum` and have a return data type explicitly declared. Unary operators can be overloaded to return any valid data type, except for `Operator -> (Pointer To Member Access)` which must return a `Type` or `Class` data type.
Binary operators must be declared outside the `Type`, `Class`, or `Enum` and have a return data type explicitly declared. Binary operators can be overloaded with valid data types, except for relational operators, which must return `Integer`.
`Let` refers to the assignment operator, as in `LET a=b`. The `Let` keyword is omitted in common practice, and is not allowed in the -lang fb dialect. However, `Let()` can be used to assign the fields of a UDT to multiple variables.
See `For`, `Step`, and `Next` for more information on overloading the `For..Next` statement for use with user defined types.
`New`, `New[]`, `Delete`, and `Delete[]` operator members are always static, even if not explicitly declared (`Static` keyword is unnecessary but allowed).
Example
`
'' operator1.bas
Type Vector2D
As Single x, y
'' Return a string containing the vector data.
Declare Operator Cast() As String
'' Multiply the vector by a scalar.
Declare Operator *= ( ByVal rhs As Single )
End Type
'' Allow two vectors to be able to be added together.
Declare Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D
'' Return the modulus (single) of the vector using the overloaded operator 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 )
`
Aligned memory allocator:

- by using the overloaded member operators "New" and "Delete", any created User object is aligned to a multiple of "ALIGN" bytes (256 bytes in this example),
- the real pointer of the allocated memory is saved just above the User pointer, in the padding block.

`
'' operator2.bas
Const ALIGN = 256
Type UDT
Dim As Byte a(0 To 10 * 1024 * 1024 - 1) '' 10 megabyte fixed array
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
`
Output example:

    '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

Small use case of the operator "[]": simplest smart pointers for byte buffers.
`
'' operator3.bas
'' A smart pointer is an object which behaves like a pointer but does more than a pointer:
'' - This object is flexible as a pointer and has the advantage of being an object,
'' like constructor and destructor called automatically.
'' - Therefore, the destructor of the smart pointer will be automatically called
'' when this object goes out of scope, and it will delete the user pointer.
'' Example of simplest smart pointers for byte buffers:
'' - Constructor and destructor allow to allocate, deallocate, and resize the byte buffer.
'' - Pointer index operator allows to access buffer elements.
'' - Copy-constructor and let-operator are just declared in private section,
'' in order to disallow copy construction and any assignment.
Type smartByteBuffer
Public:
Declare Constructor (ByVal size As UInteger = 0)
Declare Operator [] (ByVal index As UInteger) ByRef As Byte
Declare Destructor ()
Private:
Declare Constructor (ByRef rhs As smartByteBuffer)
Declare Operator Let (ByRef rhs As smartByteBuffer)
Dim As Byte Ptr psbb
End Type
Constructor smartByteBuffer (ByVal size As UInteger = 0)
This.destructor()
If size > 0 Then
This.psbb = New Byte[size]
Print "Byte buffer allocated"
End If
End Constructor
Operator smartByteBuffer.[] (ByVal index As UInteger) ByRef As Byte
Return This.psbb[index]
End Operator
Destructor smartByteBuffer ()
If This.psbb > 0 Then
Delete[] This.psbb
This.psbb = 0
Print "Byte buffer deallocated"
End If
End Destructor
Scope
Dim As smartByteBuffer sbb = smartByteBuffer(256)
For I As Integer = 0 To 255
sbb[I] = I - 128
Next I
Print
For I As Integer = 0 To 255
Print Using "#####"; sbb[I];
Next I
Print
End Scope
`
Dialect Differences

- Only available in the -lang fb dialect.

See also

- `Class`
- `Enum`
- `Type`