FreeBASIC Union
目次→言語リファレンス→変数とデータ型→ユーザ定義型→UNION←オリジナル・サイト
共用体(2つ以上の変数が、同じメモリ領域を共有する)の、ユーザ定義型を、宣言します。
構文:
パラメタ:
typename
Unionの名前
fieldname
データ項目メンバーの名前
member function declaration
サポートされるメンバー関数の、いずれか
記述:
Union のデータ要素は、メモリ内の同じ場所を占有します(
Union のすべてのデータ要素に対して同じメモリアドレス)。
Union のデータ要素は、単純なデータ・フィールド、またはデータ・フィールドの匿名の
Type ブロックです。
Union のサイズは、最大のデータ要素のサイズです。
それらは共通のメモリ空間を占有するので、同時には通常1つのデータ要素しか使えません。(所与のデータ要素が書き込まれると、共通の和集合空間を共有する他のデータ要素は、上書きまたは破壊されるかもしれません。)
Type と同様に、
Union はフィールドの位置合わせにオプションの
Field = number 指定子を使えます。また、
Extends キーワードを使うことで継承もサポートしています。
Type とは異なり、
Union は、可変長の文字列や配列を含めることはできません。
さらに一般的には、構築子や解体子を含むオブジェクト・フィールド(または基底)を持つことはできません。
したがって、
Union は、
Object 組み込み型からの継承を、サポートしません。
Union は、
Constructor,
Destructor,
Function,
Operator,
Property,
Sub を含む、メンバ手続きをサポートしています。
Union のすべてのメンバーは公開されています。アクセス修飾子はサポートされていません。
UNION の初期化要素は、UNION の最初のメンバーとのみペアにして、残りはスキップする必要があります。
Union は、さまざまな種類の入れ子にされた
Type や
Union(共用体) を含めることができます:
- 入れ子にした匿名の 型/共用体:
- 入れ子にされた匿名の Type や Union(共用体) により、データ メンバーを必要に応じてグループ化できます。
- 匿名の Type または 匿名の Union は、交互に入れ子にすることを条件に、入れ子にすることができます。
- 入れ子にされた匿名の 型/共用体は、手続きメンバーまたは静的データ メンバーを持つことはできません (Type/Union という名前のローカル スコープと同じ制限)。
- 入れ子にされた名前付き 型/共用体:
- 入れ子にされた名前付き 型/共用体は、(名前付き)Type/Union 名前空間の内側で、場所のアクセス権に従って内部構造を宣言することができます。
- 名前付き型/共用体で実行できるほとんどすべてのことは、ネストされた名前付き型/共用体でも実行できます。
- Type/Union 間に循環依存関係がある場合、入れ子にされた名前付き型/共用体を使うと、型エイリアスの使用や前方参照を回避できます。
- 入れ子にされた型定義:
- Nested Type-Def では、Type/Union の内部で、その場所のアクセス権に応じた内部型(Alias)を宣言することができます。
主構造体(Type または Union)は常に名前を付ける必要があり、他の (入れ子にされた) 構造は無名または名前付きにすることができます。
Union は、ユーザー定義型と同様の方法で、多重定義された演算子手続きに渡すことができます。
注意: Union がベースを拡張すると、新しいフィールドはベースに追加されませんが、ベースは派生 Union に追加されるため、混乱を招く可能性があります。
これは派生した Union のデータ要素が、ベースと同じメモリ空間を共有できることを意味します(ここではベースが、
Union かどうかは関係ありません)。
もちろん危険かもしれませんが、それは Union の問題です。
基本のみが
Union の場合、派生 UDT のデータ要素の影響を受けません。
Union は、複雑なデータ要素(すなわち、コンストラクタ/デストラクタを持つ UDT、または動的文字列)を持つことができないため、派生した Union は複雑な基底を持つ(含む)ことができません。
注意: fbcバージョン1.20.0 以降、STRING*N 項目を含む共用体は、最初の項目が STRING*N 型であれば空白に初期化され、そうでなければ 0 に初期化されます。(fbcバージョン1.20.0以前の STRING*N 項目と同様)。
例:
' Example 0: リトルエンディアン
' 整数値が大きい場合 (次の Ulong データ型のように),
' バイトはメモリ内で 'リトルエンディアン' バイト順に並べられます。
' (最下位バイトが最初に格納されます).
Union UDU
ul As Ulong ' 32-bit data type
Type
ub0 As UByte ' 8-bit data type
ub1 As UByte ' 8-bit data type
ub2 As UByte ' 8-bit data type
ub3 As UByte ' 8-bit data type
End Type
End Union
Dim As UDU u
u.ul = &h12345678
Print Hex(u.ul) ' Result: 12345678
Print Hex(u.ub3), Hex(u.ub2), Hex(u.ub1), Hex(u.ub0) ' Result: 12 34 56 78
Sleep
' Example 1: 一度に1人の組合員にしかアクセスできない
Union member
username As String * 32
posts As Ulong
End Union
Dim As member userX
userX.username = "Samantha"
userX.posts = 1234
Print userX.username '
ユーザー名の値が破損しています。投稿に割り当てられた最終値が、同じメモリ位置を占有しているためです。
' ' (
そしてこれが投稿の値が上手く表示されている理由です)
Print userX.posts
Print
Dim As member userY
userY.posts = 4321
userY.username = "Alexander"
Print userY.username
Print userY.posts '
投稿の値が破損しています。username に割り当てられた最終値が同じメモリ位置を占有しているためです。
' ' (
これが username の値がよく表示される理由です)
Print
Sleep
' Example 2:
RGBA キーワードに代わるもので、基本色の値を取得できるようにする
Union BGRA_UNION
colour As ULONG
Type
blue As UByte
green As UByte
red As UByte
Alpha As UByte
End Type
End Union
Dim ubgra As BGRA_UNION
' Setting the individual color values...
ubgra.red = &h33
ubgra.green = &hcc
ubgra.blue = &h66
' We can get a ULONG value
Print Hex(ubgra.colour) ' Result: 33CC66
Print
' Setting a ULONG value...
ubgra.colour = &h228844
' We can get the individual color values
Print Hex(ubgra.red) ' Result: 22
Print Hex(ubgra.green) ' Result: 88
Print Hex(ubgra.blue) ' Result: 44
Print
Sleep
' Example 3.
' Define a simple union.
Union AUnion
a As UByte
b As UInteger
End Union
' 名前なし共用体を使って複合型を定義します。
Type CompType
s As String * 20
ui As UByte 'Flag to tell us what to use in union.
Union
au As UByte
bu As UInteger
End Union
End Type
' 共用体で何を使うかを知らせるためのフラグ。
' 特定の時点で共用体の単一の要素のみを使うことが重要であるため。
Const IsInteger = 1
Const IsUByte = 2
Dim MyUnion As AUnion
Dim MyComposite As CompType
' 選択基準なしで、共用体内の1つのフィールドだけが設定されます。
MyUnion.a = 128
MyComposite.s = "Type + Union"
MyComposite.ui = IsInteger ' Tells us this is an integer union.
MyComposite.bu = 1500 ' Field set according to the above flag.
Print "Simple Union: ";MyUnion.a
Print MyComposite.s & ": ";
If MyComposite.ui = IsInteger Then
Print MyComposite.bu
ElseIf MyComposite.ui = IsUByte Then
Print MyComposite.au
Else
Print "Unknown Type."
End If
Print
Sleep
' Example 4: ネストされた名前付き共用体を使う
Type T
Union U
a As Short
Type
b1 As Byte
b2 As Byte
End Type
Declare Sub proc(ByVal _b1 As Byte, ByVal _b2 As Byte)
End Union
m As U
Declare Sub proc()
End Type
Sub T.U.proc(ByVal _b1 As Byte, ByVal _b2 As Byte)
This.b1 = _b1
This.b2 = _b2
End Sub
Sub T.proc()
Print This.m.b1, This.m.b2, This.m.a
End Sub
Dim x As T
x.m.proc(1, 2)
x.proc()
Sleep
' Example 1: bitfields.
Type unitType
Union
Dim attributeMask As UInteger
Type ' 32-bit uintegers can support up to 32 attributes.
isMilitary : 1 As UInteger
isMerchant : 1 As UInteger
End Type
End Union
End Type
Dim myunit As unitType
myunit.isMilitary = 1
myunit.isMerchant = 1
Print myunit.isMilitary ' Result: 1.
Print myunit.isMerchant ' Result: 1.
Print myunit.attributeMask ' Result: 3.
Sleep
' Example 2.
'union を定義します
Union AUnion
a As UByte
b As Integer
End Union
'合成型を定義します
Type CompType
s As String * 20
ui As Byte 'union で、何を使うべきかを、私たちに伝えるための、旗(フラグ)
Union
au As UByte
bu As Integer
End Union
End Type
'union で、何を使ったらよいかを、私たちに知らせるための旗。
'union の、一つの要素を使えるだけです。
Const IsInteger = 1
Const IsUByte = 2
Dim MyUnion As AUnion
Dim MyComposite As CompType
'union で、1つの値しか設定できません
MyUnion.a = 128
MyComposite.s = "Type + Union"
MyComposite.ui = IsInteger 'これは、整数 union であることを、伝えています
MyComposite.bu = 1500
Print "Union: ";MyUnion.a
Print "Composite: ";
If MyComposite.ui = IsInteger Then
Print MyComposite.bu
ElseIf MyComposite.ui = IsUByte Then
Print MyComposite.au
Else
Print "Unknown type."
End If
Sleep
バージョン:
- fbc 1.10.0 〜: 入れ子にされた名前付き型/共用体機能が追加されました。
方言差:
-
Union ブロックの中で定義された関数としての、オブジェクト関連の特徴は、-lang fb 方言だけでサポートされます。
- 別名 __Unionと共に参照をつけないと、-lang qb 方言で利用できません。
QBからの違い:
参照:
ページ歴史:2024-03-07 06:47:32
日本語翻訳:WATANABE Makoto、原文著作者:SysOp