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 支持成员过程,包括 Constructor、Destructor、Function、Operator、Property 和 Sub。Union 的所有成员都是公共的,不支持访问修饰符。

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 是开源项目,与微软公司无隶属关系