Типы как объекты
 
Пример: перегружаемые операторы и процедуры

Описание

!!! Запиши меня !!!

'' Пример типа , с доступными методами и операторами
'' Практически это бессмысленный пример, потому что
'' элемент данных представляет собой только Integer.  
'' Пример служит только в качестве демонстрации и руководства.
''
'' Существует множество других комбинаций, которые могут
'' использоваться в передаче параметров.  Для простоты
'' В этом примере использует только byref и тип T, где это возможно

'' Тип 'DataType' включен, чтобы показать, что может
'' использоваться любой тип данных

Type DataType As Integer

'' Тип «UDT» включен, чтобы показать где
'' определяемый пользователем тип может использоваться

Type UDT
  value As DataType
End Type

'' Наш основной тип
Type T
  value As DataType
  value_array( 0 ) As DataType

  '' let, cast, операторы комбинированного присваивания,
  '' конструкторы, и деструкторы, должны быть объявлены
  '' внутри типа.
  ''
  '' Параметры могут передаваться как ByVal или ByRef
  '' в большинстве своем(Все? - убедитесь в этом).

  ''
  '' Все процедуры могут быть перегружены с различными
  '' типами параметров. Во многих случаях в этом нет
  '' необходимости, поскольку ТИП может быть приведен и
  '' преобразован в зависимости от методов CAST
  '' Компилятор будет в своих лучших проявлениях
  '' для оценки заявления и выражения, если
  '' есть достаточно информации для выполнения
  '' операции.

  ''
  '' Для примера,
  '' Даже при том, что оператор += может не перегружаться,
  '' но оператор let и оператор + будут, компилятор преобразует
  ''  T += datatype
  '' в T = T + datatype.

  '' Нестатические элементы должны быть
  '' продекларированы внутри типа
  ''
  '' Все нестатические элементы неявно
  '' передают скрытый параметр **THIS**
  '' в тот тип ТИП, в котором они
  '' продекларированы.

  ''
  '' Нестатические элементы перегруженных операторов
  '' не возвращают тип. Все операции сделаны, чтобы
  '' скрыть этот параметр

  ''
  '' Свойства: Могут быть значения свойств или единственное значение индексированных свойств
  '' GET/SET методы должны быть продекларированы, если используются.

  '' Декларация нестатических элементов:

  '' Присваивание

  Declare Operator Let ( ByRef rhs As T )
  Declare Operator Let ( ByRef rhs As DataType )

  '' Могут быть перегружены для возврата нескольких типов

  Declare Operator Cast () As String
  Declare Operator Cast () As DataType

  '' Комбинированное присваивание

  Declare Operator += ( ByRef rhs As T )
  Declare Operator += ( ByRef rhs As DataType )

  Declare Operator -= ( ByRef rhs As DataType )
  Declare Operator *= ( ByRef rhs As DataType )
  Declare Operator /= ( ByRef rhs As DataType )
  Declare Operator \= ( ByRef rhs As DataType )
  Declare Operator Mod= ( ByRef rhs As DataType )
  Declare Operator Shl= ( ByRef rhs As DataType )
  Declare Operator Shr= ( ByRef rhs As DataType )
  Declare Operator And= ( ByRef rhs As DataType )
  Declare Operator Or= ( ByRef rhs As DataType )
  Declare Operator Xor= ( ByRef rhs As DataType )
  Declare Operator Imp= ( ByRef rhs As DataType )
  Declare Operator Eqv= ( ByRef rhs As DataType )
  Declare Operator ^= ( ByRef rhs As DataType )

  '' Адрес из

  Declare Operator @ () As DataType Ptr

  '' Конструкторы могут быть перегружены

  Declare Constructor()
  Declare Constructor( ByRef rhs As T )
  Declare Constructor( ByRef rhs As DataType )

  '' Может существовать только один деструктор

  Declare Destructor()

  '' Нестатические функции-элементы и процедуры при
  '' перегрузке должны иметь различные параметры


  Declare Function f( ) As DataType
  Declare Function f( ByRef arg1 As DataType ) As DataType

  Declare Sub s( )
  Declare Sub s( ByRef arg1 As T )
  Declare Sub s( ByRef arg1 As DataType )

  '' Свойства

  Declare Property p () As DataType
  Declare Property p ( ByRef new_value As DataType )

  Declare Property pidx ( ByVal index As DataType ) As DataType
  Declare Property pidx ( ByVal index As DataType, ByRef new_value As DataType )

End Type

'' Они должны быть глобальные процедуры
'' Глобальные не начинаются с названия типа


'' По крайней мере один параметр должен быть типа 'T'
'' Для простоты, тип 'T' всегда дается сначала для двоичного ops
'' в этом примере


Declare Operator - ( ByRef rhs As T ) As DataType
Declare Operator Not ( ByRef rhs As T ) As DataType

Declare Operator -> ( ByRef rhs As T ) As UDT
Declare Operator * ( ByRef rhs As T ) As DataType

Declare Operator + ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator - ( ByRef lhs As T, ByRef rhs As DataType ) As DataType 
Declare Operator * ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator / ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator \ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Mod ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Shl ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Shr ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator And ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Or ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Xor ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Imp ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Eqv ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator ^ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator = ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator <> ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator < ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator > ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator <= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType

'' Глобальные процедуры (процедуры и функции) могут также принимать тип
'' как параметр или вернуть его в качестве значения, как это можно было сделать
'' в предыдущих версиях FreeBASIC.
'' Нет примера. Смотрите function или sub в руководстве.


'' Все элементы типа определены вне типа

'' Нестатические элементы должны иметь префикс с именем типа
'' в данном случае 'T'


'' Разрешение имен в пространстве имен такое же как и у других
'' процедур/функций.  Используйте USING или префикс имени пространства имен


Operator T.let ( ByRef rhs As T )
  value = rhs.value  
End Operator

Operator T.let ( ByRef rhs As DataType )
  value = rhs  
End Operator

Operator T.cast ( ) As String
  Return Str( value )
End Operator

Operator T.cast ( ) As DataType
  Return value
End Operator

Operator T.+= ( ByRef rhs As T )
  value += rhs.value
End Operator

Operator T.+= ( ByRef rhs As DataType )
  value += rhs
End Operator

Operator T.-= ( ByRef rhs As DataType )
  value -= rhs
End Operator

Operator T.*= ( ByRef rhs As DataType )
  value *= rhs
End Operator

Operator T./= ( ByRef rhs As DataType )
  value /= rhs
End Operator

Operator T.\= ( ByRef rhs As DataType )
  value \= rhs
End Operator

Operator T.mod= ( ByRef rhs As DataType )
  value Mod= rhs
End Operator

Operator T.shl= ( ByRef rhs As DataType )
  value Shl= rhs
End Operator

Operator T.shr= ( ByRef rhs As DataType )
  value Shr= rhs
End Operator

Operator T.and= ( ByRef rhs As DataType )
  value And= rhs
End Operator

Operator T.or= ( ByRef rhs As DataType )
  value Or= rhs
End Operator

Operator T.xor= ( ByRef rhs As DataType )
  value Xor= rhs
End Operator

Operator T.imp= ( ByRef rhs As DataType )
  value Imp= rhs
End Operator

Operator T.eqv= ( ByRef rhs As DataType )
  value Eqv= rhs
End Operator

Operator T.^= ( ByRef rhs As DataType )
  value ^= rhs
End Operator

Operator T.@ () As DataType Ptr
  Return( Cast( DataType Ptr, @This ))
End Operator


'' Конструкторы:

Constructor T()
  value = 0
End Constructor

Constructor T( ByRef rhs As T )
  value = rhs.value
End Constructor

Constructor T( ByRef rhs As DataType )
  value = rhs
End Constructor

'' Может существовать только один деструктор

Destructor T()
  '' очистка, ничего не делается в этом примере
End Destructor



'' Глобальным необходимо указать все аргументы и возвращаемый тип

Operator - ( ByRef rhs As T ) As DataType
  Return (-rhs.value)
End Operator

Operator Not ( ByRef rhs As T ) As DataType
  Return (Not rhs.value)
End Operator

Operator -> ( ByRef rhs As T ) As UDT
  Return Type(4)
End Operator

Operator * ( ByRef rhs As T ) As DataType
  Return 5
End Operator

Operator + ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value + rhs)
End Operator

Operator - ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value - rhs)
End Operator

Operator * ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value * rhs)
End Operator

Operator / ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value / rhs)
End Operator

Operator \ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value \ rhs)
End Operator

Operator Mod ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Mod rhs)
End Operator

Operator Shl ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Shl rhs)
End Operator

Operator Shr ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Shr rhs)
End Operator

Operator And ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value And rhs)
End Operator

Operator Or ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Or rhs)
End Operator

Operator Xor ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Xor rhs)
End Operator

Operator Imp ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Imp rhs)
End Operator

Operator Eqv ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value Eqv rhs)
End Operator

Operator ^ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value ^ rhs)
End Operator

Operator = ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value = rhs)
End Operator

Operator <> ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value <> rhs)
End Operator

Operator < ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value < rhs)
End Operator

Operator > ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value > rhs)
End Operator

Operator <= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value <= rhs)
End Operator

Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
  Return (lhs.value >= rhs)
End Operator


'' Нестатические элементы-методы

Function T.f( ) As DataType
  Dim x As DataType
  Return x
End Function

Function T.f( ByRef arg1 As DataType ) As DataType
  arg1 = this.value
  Return value
End Function

Sub T.s( )
  '' ссылается на тип , используя
  
  '' with блок
  With This
    .value = 1
  End With
  
  '' доступ к полю
  this.value = 2
  
  '' непосредственно
  value = 3

End Sub

Sub T.s( ByRef arg1 As T )
  value = arg1.value
End Sub

Sub T.s( ByRef arg1 As DataType )
  value = arg1
End Sub

Property T.p () As DataType
  '' GET свойство
  Return value
End Property

Property T.p ( ByRef new_value As DataType )
  '' SET свойство
  value = new_value
End Property

Property T.pidx ( ByVal index As DataType ) As DataType
  '' GET индексированное свойство
  Return value_array( index )
End Property

Property T.pidx ( ByVal index As DataType, ByRef new_value As DataType )
  '' SET индексированное свойство
  value_array( index ) = new_value
End Property


'' new, delete, delete[]

'' Выделение памяти для объекта
Dim X As T Ptr = New T

'' Удаление объекта
Delete X

'' Выделение памяти для объекта вектора
Dim Xlist As T Ptr = New T[10]

'' Удаление объекта вектора
Delete[] Xlist


См. также