Type や
Class のメンバーに、アクセスできる手続き。
宣言と定義
メンバー手続きを宣言して、定義します。
用法
メンバー手続きを呼びます。
隠されたパラメタ、This
非静的メンバー手続きを呼ぶ、インスタンスへの、暗黙のアクセス。
アクセス権
メンバー手続きで、他のメンバーを参照します。
多重定義
同じ名前で、複数のメンバー手続きを、宣言します。
静的メンバー手続き
非静的メンバー手続きとの違い。
- 特に指定しない限り、'メンバー手続き'という用語は、静的と非静的の両方のメンバーの手続きを示します。
宣言と定義
メンバー手続きは、普通のモジュール・レベルの手続きと同じように、宣言します。ただし、メンバー手続きは、
Type や
Class 定義の中で宣言されて、
Type や
Class 定義の外部で定義される点が、異なります。
[1]
'' foo1.bi
Type foo
Declare Sub f (As Integer)
Declare Function g As Integer
i As Integer
End Type
Sub foo.f (n As Integer)
Print n
End Sub
Function foo.g As Integer
Return 420
End Function
用法
'' ... 前と同様に、foo は、非静的メンバーと共に ...
#include once "foo1.bi"
Dim bar As foo
bar.f(bar.g())
隠されたパラメタ、This
メンバー手続きは、メンバー手続きが宣言されるとき、実際に、追加されるパラメータがあります。
[3]
メンバー手続きが、インスタンスの名前と、
演算子 . (Member access) を使って、呼ばれるとき、そのインスタンスの参照は、呼び出しの中で、他の引数と共に、渡されます。そして、メンバー手続きが、インスタンスに直接アクセスできるようにします。
コンパイラによって加えられた追加パラメタは、
This と呼ばれます。そして、コンパイラによって加えられた追加パラメタは、参照なので、
This への変更は、メンバー手続きが呼ばれたときに、メンバー手続きに渡された、インスタンスへの変更そのものです。
ちょうど他の変数と同じように
This を使って、つまり、
This を、同じ型のオブジェクトを取る手続きに渡すことで、他のメンバー手続きを呼ぶことができます。そして、
演算子 . (Member access) などを使っている、メンバーデータに、アクセスすることができます。
しかし、通常は、
This を、明示的に使う必要は、ありません。
メンバー手続きは、メンバー手続きが、名前で直接に他のメンバーに渡されるインスタンスの、他のメンバーを参照できます。
This や
演算子 . (Member access) を使って、名前に資格を与える必要はありません。
This を使ってメンバ名に資格を与える必要がある唯一の場合は、メンバ名が隠される、例えば、パラメタや、局所変数で、の時です。
これらの状況で、メンバ名に資格を与えるのは、これらの隠されたメンバ名を参照する、唯一の方法です。
注意:
型の外でグローバルとして定義された重複シンボルにアクセスするには、頭辞として 1つまたはできれば 2つの点を追加します:.SomeSymbol またはできれば ..SomeSymbol (With..End With ブロック内の場合は ..SomeSymbol のみ)。
下の例は、
This キーワードを、メンバーデータの名前が、パラメタと局所変数で隠れているメンバーデータを参照するために、使っています:
Type foo
Declare Sub f (i As Integer)
Declare Sub g ()
i As Integer = 420
End Type
Sub foo.f (i As Integer)
'' パラメタが T.i を隠しているので、使うために資格を与える必要があります:
Print This.i
End Sub
Sub foo.g ()
'' 局所変数が T.i を隠しているので、使うために資格を与える必要があります:
Dim i As Integer
Print This.i
End Sub
アクセス権
普通のモジュール・レベル手続きと異なって、メンバー手続きは、メンバー手続きが宣言される、
Type や
Class のメンバーへの、完全なアクセス権を持っています。
メンバー手続きは、
Type や
Class の、公開、保護、あるいは非公開の、メンバーを、参照できます。
多重定義
メンバー手続きは、別のメンバー手続きと同じ名前で、宣言できます。与えられるパラメタが、数か型で異なっている場合に限ってですが。
これは多重定義と呼ばれます。
パラメタだけが、手続きの宣言が有効な多重定義であるかどうかを決定するのに、使われます。
例えば、
Type か
Class は、同じ名前で、静的と、非静的のメンバーの手続きを持つことができます。あるいは、同じ名前で、
Sub と
Function メンバー手続きを持つことができます。
モジュール・レベル手続きは、多重定義を許容する宣言で、
Overload 節を指定する必要があります。これと異なって、メンバー手続きは、デフォルトで「多重定義-可能」で、
Overload 節は不要です。
Type T
Declare Sub f
'' パラメータの異なった数:
Declare Sub f (As Integer)
'' パラメータの異なった型:
Declare Sub f (ByRef As String)
'' また、パラメタは異なっています:
Declare Function f (As UByte) As Integer
'' 次の3つのメンバーは、エラーを引き起こすでしょう
'' パラメタの数、そして/または、型は、違っていません:
'' Declare Function f As Integer
'' Declare Function f (As UByte) As String
'' Declare Static Function f (As UByte) As Integer
'' ...
somedata As Any Ptr
End Type
静的メンバー手続き
静的メンバー手続きは、非静的メンバー手続きと同じやり方で、宣言されて、定義されます。
Static キーワードが、宣言と定義の前に来ます。
Static キーワードを使って定義するメンバー手続きは、
Type か
Class 定義で、
Static キーワードで宣言しなければなりません。さもなければ、コンパイラはエラーを発生します。
非静的メンバー手続きと同様に、
Type か
Class 定義で、合致した宣言なしで静的メンバー手続きを定義すると、エラーになります。
これを、
Static キーワードを手続きヘッダーに追加して、手続き定義の変数とオブジェクトのために静的ストレージを指定する手続き定義と、間違えないでください。
しかしながら、
Static キーワードは、両方の文脈で使用できます。
静的メンバー手続きは、静的変数とオブジェクト記憶装置で、定義できます。
下の例は、2つの静的メンバー手続きを宣言します。その1番目には、静的変数とオブジェクト記憶装置があります。
Static キーワードは、メンバー手続き定義で、任意であることに、注意してください:
'' foo2.bi
Type foo
Declare Static Sub f (As Integer)
Declare Static Function g As Integer
i As Integer
End Type
Static Sub foo.f (n As Integer) Static
Print n
End Sub
Function foo.g As Integer
Return 420
End Function
静的メンバー手続きは、非静的メンバー手続きと同じように、呼ばれることができます。インスタンスの名前と、メンバーアクセス演算子(
演算子 . (Member access)) を使って、手続きの名前に資格を与える必要があります。
静的メンバー手続きは、また、静的メンバー手続きが宣言された、
Type か
Class という名前と、メンバーアクセス演算子 (
演算子 . (Member access)) を使って、手続き名に資格を与えることによって、呼ばれることができます。
言い換えると、インスタンスは、静的メンバーを手続きを呼ぶために、必要ありません。
下の例は、上の例のコードを使って、静的なメンバー手続きを呼ぶ、両方の方法を示しています:
'' ... 前と同様、foo は静的メンバーと共に ...
#include once "foo2.bi"
Dim bar As foo
bar.f(foo.g())
非静的メンバー手続きが、付加的な
This パラメタで宣言されるのと異って、静的メンバー手続きは、呼ばれるとき、インスタンスを渡されません。
このため、静的メンバー手続きは、定数、列挙、他の静的メンバー(データや手続き)などを参照できるだけです。これらの名前に、資格は不要です。
静的メンバー手続きは、インスタンスで資格があると、まだ非静的メンバーを参照できます。例えば、:
パラメタや局所変数。
下の例は、静的な手続きから、非静的メンバーを参照します:
Type foo
Declare Static Sub f (ByRef As foo)
i As Integer
End Type
Sub foo.f (ByRef self As foo)
'' OK、self は foo のインスタンスです:
Print self.i
'' foo インスタンスが無いので、非静的メンバーにアクセスできません
'' エラーになります:
'' Print i
End Sub
[1]
将来、メンバー手続きは、Type や Class 定義の中で、定義できるかもしれません。
[2]
静的メンバー手続きは、呼ばれるためにオブジェクト・インスタンスを必要としません。
[3]
静的メンバー手続きは、コンパイラで、この付加的なパラメタを加えさせません。それで、静的メンバー手続きは、呼ばれたオブジェクト・インスタンスにアクセスできません。