与えられた変数型のデータを別の型の変数に転送するには、変換が必要です。
式と引数の数値データ型の強制
整数型の場合、ルールは次の順位に依存します:
32bit で:
byte < ubyte < short < ushort < long < integer < ulong < uinteger < longint < ulongint
64bit で:
byte < ubyte < short < ushort < long < ulong < longint < integer < ulongint < uinteger
まず、上の順位に従って Integer より小さいすべての引数が Integer に変換されます。
次に、引数のサイズが異なる場合は、小さい方の引数が大きい方の引数に一致するように変換されます。 次に、引数の符号が異なる場合、符号付き引数は符号なし引数に変換され、他の符号と一致するように変換されます。
最後に、(U)Integer 型は以下に置き換えます:
32bit で:
the (U)Long types
64bit で:
the (U)Longint types
一方、引数の1つが Single か Double の場合、両方の引数は Double に変換および/または昇格されます。
数値データ型の変換
式や変数が割り当てられたり、パラメタとして手続きに渡されたり、手続きからその結果として戻ったとき、型変換は、それとなく黙示的に行われます。
また、CAST か、内蔵の変換関数の1つを(標準関数の中で)使ったとき、変換は、明示的に行われます。
整数を整数に。符号付き、符号無しのどんな組み合わせに対しても
- あらゆる整数型を、より小さい整数型に変換するとき:
最下位ビットは保持されます。
- あらゆる整数型を、より大きい整数型に変換するとき:
最上位ビットを満たすために、符号拡張されます。
整数を Single か Double に
Double を Single に
- 精度を落とす可能性
- Double の値が Single の範囲を超えているなら、結果は、+/- INF(上限) です。
Double か Single を整数に
- 精度を落とす可能性
- 浮動小数の値が、目標の型の範囲を超えているなら、結果が未定義です。
実行時エラーは、発生しません。
ユーザーデータ型構築子と演算子を使う変換
組み込み型の間(上記の数値型の間、または、文字列型の間のような、標準の型の間)の変換では、コンパイラは、ユーザからの指示の必要なしで、何をすべきかわかっています。
これは、黙示的な内部転換(または強制)と呼ばれています。
2つの型の少なくとも1つが UDT(ユーザー定義型)のとき、ユーザーは、変換を行う方法を定義するために、いくつかの UDT 手続きをコーディングする必要があります。
そして、ユーザーが、使われる UDT 手続きを指定するなら、変換実行は明示的に行われます。ユーザーが選択をコンパイラに任せるならば、黙示的に行われます。
UDT の世界では、変換は 3つのメンバー手続きで制御できます:
- 単一引数の構築子:オブジェクトを初期化するために、特定の型からの変換を可能にします。
- 代入演算子:代入の特定の型からの変換を可能にします。
- 型変換演算子:特定の型への変換を可能にします。
黙示的な初期化 ('Dim As UDT u = v') を伴う構築の場合、コンパイラは次の優先順位に従って検索します:
- まず、一致するコンストラクター (v 型からの u 型)。
- 次に、キャスト演算子 (v 型から特殊型 (*) へ) とそれに対応する変換コンストラクター (特殊型から u 型 (*))。
- 3 番目に、マッチしたキャスト演算子 (v 型から u 型へ)。
(一致する let 演算子 (v 型からの u 型) は、黙示的な初期化を伴う構築でコンパイラによって検索されません)
v 型パラメーターを渡すときの黙示的なコピー構築 ('Byval As u_type') の場合、コンパイラーは次の優先順位に従って検索します:
- まず、一致するコンストラクター (v 型から u 型)。
- 次に、キャスト演算子 (v 型から特殊型 (*) へ) とそれに対応する変換コンストラクター (特殊型から u 型 (*) の場合)。
- 3 番目に、マッチしたキャスト演算子 (v 型から u 型へ) です。
(一致する let 演算子 (v 型からの u 型) は、黙示的な初期化を伴う構築でコンパイラによって検索されません。)
v 型パラメーターを渡すときの黙示的な参照渡し ('Byref As u_type') の場合、コンパイラーは次の優先順位に従って検索します:
- まず、一致するキャスト演算子 (v 型から u 型へ)。
- 次に、一致するコンストラクター (v 型からの u 型)。
- 最後に、キャスト演算子 (v 型から特殊型 (*) へ) とそれに対応する変換コンストラクター (特殊型から u 型 (*) )。
(一致する let 演算子 (v 型からの u 型) は、黙示的な参照渡しでコンパイラによって検索されません。)
黙示的な代入 ('u = v')、または代入による関数からの黙示的な戻り ('Function = v') で u 型を返す関数の場合、コンパイラは次の優先順位に従って検索します:
- 最初に、一致する let 演算子 (v 型からの u 型)。
- 次に、キャスト演算子 (v 型から特殊型 (*) へ) とそれに対応する let 演算子 (特殊型から u 型 (*) へ)。
- 3 番目に一致するキャスト演算子 (v 型から u 型へ)。
- 最後に、一致するコンストラクター (v 型からの u 型) と明示的な copy-let 演算子 (u 型)。
u 型を返す関数を使ってすぐに終了する ('Return v') ことによる関数からの黙示的な戻りの場合、コンパイラは次の優先順位に従って検索します:
- まず、一致するコンストラクター (v 型からの u 型)。
- 次に、キャスト演算子 (v 型から特殊型 (*) へ) とそれに対応する変換コンストラクター (特殊型から u 型 (*) )。
明示的なコピー コンストラクター (u 型) が存在する場合:
- 3 番目に一致するキャスト演算子 (v 型から u 型へ)。
- 最後に、マッチした let 演算子 (v 型からの u 型)。
それ以外 (明示的なコピー コンストラクター (u 型) が存在しない)の場合:
- 3 番目に、一致する let 演算子 (v 型からの u 型)。
- 最後に、一致するキャスト演算子 (v 型から u 型へ)。
特殊な型 (*) : ポインターか文字列、または UDT で u 型に明示的なコピー コンストラクター/明示的なコピー代入演算子がない場合
注意:
変換プロセス自体に直接影響するメンバー手続きのみが、上記に書かれています:
- 黙示的な定義のみで十分で明示的な定義がない場合、コピー コンストラクター (u 型) と copy-let 演算子 (u 型) は書かれていません。
- デフォルト コンストラクター (u 型) は引用されませんが、'Function = v' の場合に黙示的なバージョンが常に必要です。それ以外の場合は別の明示的なコンストラクター (u 型) が定義されている場合は明示的なバージョンが必要です。変換プロセス自体には必要ありません。
例:
変換機能を強調する、非常に単純な構文の例。
型変換演算子(明示と黙示)、構築子(明示と黙示)、Let 演算子(黙示)を使います:
Type UDT
Dim As Integer I
Declare Operator Cast () As Integer
Declare Constructor (ByVal I0 As Integer)
Declare Operator Let (ByVal I0 As Integer)
End Type
Operator UDT.Cast () As Integer
Return This.I
End Operator
Constructor UDT (ByVal I0 As Integer)
This.I = I0
End Constructor
Operator UDT.Let (ByVal I0 As Integer)
This.I = I0
End Operator
Dim As Integer J = 12
Dim As UDT u1 = UDT(J) '' 定義済みの "Constructor(Byval As Integer)" 演算子を使って、明示的に初期化する構築
Print u1.I
Dim As UDT u2 = J '' 定義済み "Constructor(Byval As Integer)" 演算子を用いて、コンパイラによる潜在的な初期化による構築
Print u2.I
Print
u1.I = 34
J = Cast(Integer, u1) '' 定義済みの "Cast() As Integer" 演算子を用いて、明示的に代入
Print J
Dim As Integer K
K = u1 '' 定義済み "Cast() As Integer" 演算子を用いて、コンパイラにより黙示的に代入
Print K
Print
J = 56
u1 = J '' 定義済み "Let(Byval As Integer)" 演算子を用いて、コンパイラにより黙示的に代入
Print u1.I
Print
Sleep
参照: