型構造を使ってユーザーオブジェクトを定義するとき、多くの種類の手続きを、データ項目スケルトンに追加して、ユーザーが簡単に使えるようにできます:
- Sub、Function、Properties のメンバー。
- コンストラクタとデストラクタ。
- 演算子の多重定義(型定義の内側と外側)。
次の例は、宣言と定義の構文テンプレートです:
'' サンプル型は、利用可能なメソッドと演算子を示します。
'' 実際に、これは、ただデータ・メンバーが整数なので、無意味な例です。
'' これは、構文のガイドとしてのみ役立ちます。
''
'' 渡されたパラメータで使える他の多くの組合せが、あります。
'' 単純化のために、
'' この例では、全ての所で、byref と 型 T だけを使います。
'' 型「DataType」は、何かデータ型が使われることを示すために、含めています。
Type DataType As Integer
'' 型「UDT」は、UDT データ型だけが使えることを示すために、含めています。
Type UDT
value As DataType
End Type
'' 主の型です
Type T
value As DataType
value_array( 0 ) As DataType
'' Let, cast, 複合代入演算子, 構築子, 破壊子は、
'' 型の中で宣言しなければなりません。
''
'' パラメータは、ほとんどで Byval または Byref で渡すことができます。
'' (すべて? - これを確かめてください).
''
'' すべての proc は、パラメータとして異なる型を多重定義することができます。
'' 多くの場合、TYPE は、それが公開する CAST 方法に従い、
'' 強制され変わることができるので、これは必要でありません。
'' コンパイラは、操作を完了するのに十分な情報があるならば、
'' 命令文と式を評価するために、そのベストを尽くします。
'' (Proc とは、ブロックをコンテキスト(ローカル変数のスコープやスタックフレーム)
'' とともにオブジェクト化した手続きオブジェクト?)
''
'' 例えば、
'' 演算子 += は多重定義できませんが、
'' 演算子 Let と、演算子 + は、
'' コンパイラは、T += datatype を、
'' T = T + datatype と変換します。
'' 非静的メンバーは、型の中で、宣言しなければなりません。
''
'' 全ての非静的メンバーは、
'' それらが中で宣言された TYPE と同じ型を持つ、
'' 隠れた **this** パラメータを、
'' 暗黙のうちに渡されます。
''
'' 多重定義された非静的メンバ演算子は、型を返しません。
'' すべての操作は、隠れた this パラメータの上で行われます。
''
'' Property: 値 Property または索引付き値 Property
'' Property を使うとき、GET/SET メソッドをそれぞれは、宣言しなければなりません。
'' 非静的メンバ宣言:
'' メモリの割り当て/割り当て解除
Declare Operator New ( ByVal size As UInteger ) As Any Ptr
Declare Operator New[] ( ByVal size As UInteger ) As Any Ptr
Declare Operator Delete ( ByVal buf As Any Ptr )
Declare Operator Delete[] ( ByVal buf As Any Ptr )
'' 割り当て
Declare Operator Let ( ByRef rhs As T )
Declare Operator Let ( ByRef rhs As DataType )
'' Cast は、複数の型を返すために、多重定義できます。
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 &= ( ByRef rhs As DataType )
'' のアドレス
Declare Operator @ () As DataType Ptr
'' Constructor は、多重定義できます
Declare Constructor()
Declare Constructor( ByRef rhs As T )
Declare Constructor( ByRef rhs As DataType )
'' destructor は、一つだけでかまいません
Declare Destructor()
''
多重定義 proc の非静的メンバ関数および sub には、
'' 異なるパラメーターが必要です。
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 )
'' Properties
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 )
'' Iterator
Declare Operator For ()
Declare Operator Step ()
Declare Operator Next ( ByRef cond As T ) As Integer
Declare Operator For ( ByRef stp As T )
Declare Operator Step ( ByRef stp As T )
Declare Operator Next ( ByRef cond As T, ByRef stp As T ) As Integer
End Type
'' これらは、global 手続きでなければなりません。
''
Global は、TYPE 名が前置されません。
''
少なくとも1つのパラメータは、型「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
Declare Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Declare Operator Abs ( ByRef arg As UDT ) As Double
Declare Operator Fix ( ByRef arg As UDT ) As Double
Declare Operator frac ( ByRef arg As UDT ) As Double
Declare Operator Int ( ByRef arg As UDT ) As Double
Declare Operator Sgn ( ByRef arg As UDT ) As Double
'' Global な手続き(sub と function)は、また、
'' パラメーターとして TYPE を受け取り、そして、値として TYPE を返すことができます。
'' FreeBASIC の旧バージョンでできたようにです。
'' プログラム例は、function や sub のマニュアルを参照下さい。
'' 全ての TYPE メンバは、TYPE の外で定義します。
'' 非静態メンバーには、この例「T」では、
'' 型名を前置しなければなりません。
'' NAMESPACE の名前解決は、他の sub/function と同じです。
''
USING を使うか、名前空間名に接頭辞を付けてください。
Operator T.New ( ByVal size As UInteger ) As Any Ptr
Operator = Allocate( size )
End Operator
Operator T.New[] ( ByVal size As UInteger ) As Any Ptr
Operator = Allocate( size )
End Operator
Operator T.Delete ( ByVal buf As Any Ptr )
Deallocate buf
End Operator
Operator T.Delete[] ( ByVal buf As Any Ptr )
Deallocate buf
End Operator
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.&= ( ByRef rhs As DataType )
Dim tmp As String
tmp &= Str( rhs )
End Operator
Operator T.@ () As DataType Ptr
Return( Cast( DataType Ptr, @This ))
End Operator
'' Constructors:
Constructor T()
'' default constructor
value = 0
End Constructor
Constructor T( ByRef rhs As T )
'' copy constructor
value = rhs.value
End Constructor
Constructor T( ByRef rhs As DataType )
'' custom constructor
value = rhs
End Constructor
'' There can be only one destructor
Destructor T()
'' clean-up, none in this example
End Destructor
'' Global は、すべての引数と戻り型を指定しなければなりません
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
Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
Return Val(lhs.value & rhs)
End Operator
Operator Abs ( ByRef arg As UDT ) As Double
Return Abs(arg.value)
End Operator
Operator Fix ( ByRef arg As UDT ) As Double
Return Fix(arg.value)
End Operator
Operator frac ( ByRef arg As UDT ) As Double
Return frac(arg.value)
End Operator
Operator Int ( ByRef arg As UDT ) As Double
Return Int(arg.value)
End Operator
Operator Sgn ( ByRef arg As UDT ) As Double
Return Sgn(arg.value)
End Operator
'' Nonstatic member methods
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( )
'' refer to the type using
'' with block
With This
.value = 1
End With
'' field access
This.value = 2
'' directly
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 property
Return value
End Property
Property T.p ( ByRef new_value As DataType )
'' SET property
value = new_value
End Property
Property T.pidx ( ByVal index As DataType ) As DataType
'' GET indexed property
Return value_array( index )
End Property
Property T.pidx ( ByVal index As DataType, ByRef new_value As DataType )
'' SET indexed property
value_array( index ) = new_value
End Property
Operator T.For ()
End Operator
Operator T.Step ()
End Operator
Operator T.Next ( ByRef cond As T ) As Integer
Return 0
End Operator
Operator T.For ( ByRef stp As T )
End Operator
Operator T.Step ( ByRef stp As T )
End Operator
Operator T.Next ( ByRef cond As T, ByRef stp As T ) As Integer
Return 0
End Operator
'' new, delete, delete[]
'' Allocate object
Dim X As T Ptr = New T
'' Deallocate object
Delete X
'' Allocate object vector
Dim Xlist As T Ptr = New T[10]
'' Deallocate object vector
Delete[] Xlist