Skip to content

UNION


声明联合用户自定义类型。

语法

vb
Union typename

fieldname as datatype
declare member function declaration ...
...

End Union

参数

typename

Union 的名称

fieldname

数据字段成员的名称

member function declaration

任何支持的成员函数

说明

Union 的数据元素在内存中占用公共空间(Union 的所有数据元素共用相同的内存地址)。Union 的数据元素可以是简单数据字段,也可以是数据字段的匿名 Type 块。

Union 的大小是最大数据元素的大小。

由于它们占用公共内存空间,通常在给定时间只能使用一个数据元素(当写入某个数据元素时,共享公共联合空间的其他数据元素可能被覆盖或损坏)。

Type 一样,Union 可以使用可选的 Field = number 说明符进行字段对齐,并通过使用 Extends 关键字支持继承。

Type 不同,Union 不能包含可变长度字符串和数组,更一般地说,不能有带有构造函数或析构函数的对象字段(或基类)。因此,Union 不支持从内置的 Object 类型继承。

Union 支持成员过程,包括 ConstructorDestructorFunctionOperatorPropertySubUnion 的所有成员都是公共的,不支持访问修饰符。

UNION 的初始化元素应仅与 UNION 的第一个成员配对,跳过其余成员。

Union 也可以包含嵌套的 Type 或 Union,有不同的种类:

  • 嵌套匿名 Type/Union:
  • 嵌套命名 Type/Union:
  • 嵌套类型定义:

主结构(Type/Union)必须始终命名,其他(嵌套)结构可以是匿名或命名的。

Union 可以像用户自定义类型一样传递给重载的运算符过程。

注意:当 Union 扩展一个基类时,可能会令人困惑,因为没有新字段被添加到基类,而是基类被添加到派生的 Union。这意味着派生 Union 中的数据元素可以与基类共享同一内存空间(这里无论基类是否是 Union 都无所谓)。当然这可能很危险,但这始终是 Union 的问题。

如果只有基类是 Union,那么它不会受到派生 UDT 的数据元素的影响。

由于 Union 不允许有复杂数据元素(即具有构造函数/析构函数的 UDT,或动态字符串),派生 Union 不能有(包含)复杂基类。

注意:自 fbc 版本 1.20.0 起,如果第一个字段是 STRINGN 类型,则包含 STRINGN 字段的联合将初始化为空格,否则初始化为零(如 fbc 版本 1.20.0 之前的 STRING*N 字段)。

示例

start GeSHi

vb
' Example 0: Little-endianness
' For larger integer values (as the following Ulong data type),
'   bytes are arranged in memory in 'little-endian' byte order
'   (the least significant byte gets stored first).

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

end GeSHi

start GeSHi

vb
' Example 1: Only one union member can be relevantly accessed at a time
Union member
  username As String * 32
  posts As Ulong
End Union

Dim As member userX
userX.username = "Samantha"
userX.posts = 1234

Print userX.username  ' value of username corrupted because final value assigned to posts occupies same memory location
'                     ' (and this is reason that value of posts is displayed well)
Print userX.posts
Print

Dim As member userY
userY.posts = 4321
userY.username = "Alexander"

Print userY.username
Print userY.posts  ' value of posts corrupted because final value assigned to username occupies same memory location
'                  ' (and this is reason that value of username is displayed well)
Print

Sleep

end GeSHi

start GeSHi

vb
' Example 2: Alternative to RGBA keyword and allowing to retrieve elementary colors values
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

end GeSHi

start GeSHi

vb
' Example 3.
' Define a simple union.
Union AUnion
    a As UByte
    b As UInteger
End Union
' Define a composite type with an unnamed 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

' Flags to let us know what to use in union,
' because it's relevant to only use a single element of a union at a given time.
Const IsInteger = 1
Const IsUByte = 2

Dim MyUnion As AUnion
Dim MyComposite As CompType

' Only one field within the union is set, without choice criterion.
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

end GeSHi

start GeSHi

vb
' Example 4: Using Nested Named Union
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

end GeSHi

版本

  • 自 fbc 1.10.0 起:添加了嵌套命名 Type/Union 功能。

方言差异

  • Union 块内定义的对象相关特性(如函数)仅在 -lang fb 方言中支持。
  • -lang qb 方言中不可用,除非使用别名 __Union 引用。

与 QB 的区别

  • FreeBASIC 新增

另请参阅

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系