Skip to content

Type(UDT/别名/临时)和 Union


不同的关键字 Type (UDT)、Type (Alias)、Type (Temporary) 和 Union。

定义

用户可能对 Type 和 Union 的不同关键字产生混淆(尽管文档通过不同页面对它们进行了区分):

  • Type (UDT)
  • Type(Alias)
  • Type (Temporary)
  • Union

Type/Union 结构的复杂级别:

  • 简单结构:没有成员过程(直接或间接)的命名或匿名结构。

  • 复杂结构:有成员过程(直接或间接)的命名结构。

  • 扩展结构:继承自另一个命名结构的命名结构。

Type/Union 结构也可以嵌套在另一个 Type/Union 结构中:

  • 嵌套命名 Type:嵌套在另一个命名 Type/Union 结构中的命名 Type。

  • 嵌套匿名 Type:嵌套在另一个命名或匿名 Union 结构中的匿名 Type。

  • 嵌套命名 Union:嵌套在另一个命名 Type/Union 结构中的命名 Union。

  • 嵌套匿名 Union:嵌套在另一个命名或匿名 Type 结构中的匿名 Union。

Type (Alias) 声明也可以嵌套在 Type/Union 结构中:

  • 嵌套 Type (Alias) 声明允许根据所在位置的访问权限在 Type/Union 内部声明内部别名。

描述

嵌套命名 Types/Unions 的主要目的是:

  • 允许以可理解的方式表达 Types 和 Unions 之间的关系。

  • 这样的 Type 或 Union 有自己的命名空间来组织相关符号——并提供仅针对 Types 的可见性访问(Public/Protected/Private)——以便对成员访问提供更细粒度的控制。

  • 当 Types/Unions 之间存在循环依赖时,使用嵌套命名 Type/Union 可以避免使用 Type (Alias) 和前向引用。

不使用嵌套命名 Types/Unions:

  • Types/Unions 之间仍然可以表达关系,但缺点是所有 Types/Unions 必须是公开可访问的。

  • Namespace 的使用可以帮助组织可见性范围,但问题仍然存在,即_所有_ Types/Unions 必须是可见的。

  • 在某些情况下,这允许用户(或作者本人)无意中以从未预期的方式使用 Type/Union,可能创建有效但容易出错的代码。

  • 可以通过前向声明(通过 Type (Alias))隐藏 Types/Unions 并将私有符号放在单独的模块中来减少这个问题,但这会通过代码碎片化产生新问题。

匿名 Type(或 Union):

  • 没有名称,无法通过名称引用。

  • 只能嵌套在命名 Union(或 Type)或另一个匿名 Union(或 Type)中。

  • 在嵌套它的结构中声明字段,在不同内存位置(嵌套 Type)或重叠内存位置(嵌套 Union)。

  • 字段可以被引用。

  • 不能包含任何静态成员或过程声明(直接或间接)=> 简单结构。

命名 Type(或 Union):

  • 有一个名称,可以被引用以声明字段、变量、参数、数组等的数据类型。

  • 可以单独出现,或嵌套在另一个命名 Type(或 Union)中。

  • 仅声明 Type(或 Union)。

  • 不在嵌套它的结构中声明任何字段,因此不会增加其大小。

  • 可以包含静态成员或过程声明(直接或间接)=> 简单/复杂结构。

Type/Union 结构的复杂级别与作用域位置的关系:

  • 简单结构:可以在全局/命名空间/嵌套作用域或局部作用域(如 Scope 或 Sub)中声明的命名或匿名 Type/Union。

  • 复杂结构:必须在全局/命名空间/嵌套作用域中声明、在全局/命名空间作用域中定义的命名 Type/Union。

  • 扩展结构:在能够看到其基类作用域的作用域中声明的命名 Type/Union(目前在与其基类相同的作用域中)。

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

在命名 Type/Union 中可以做的大多数事情也可以在嵌套命名 Type/Union 中完成,包括继承能力(作为基类或派生类)。

嵌套匿名 Type/Union 不能有过程成员或静态数据成员(与局部作用域内命名 Type/Union 的限制相同)。

示例

示例:'命名 Type' <- '嵌套匿名 Union' <- '嵌套匿名 Type':

start GeSHi

vb
Type T  '' named
    Union  '' anonymous
        Dim a As Short
        Type  '' anonymous
            Dim b1 As Byte
            Dim b2 As Byte
        End Type
    End Union
    Declare Sub proc()
End Type

Sub T.proc()
    b1 = 1
    b2 = 2
    Print b1, b2, a
End Sub

Dim x As T
x.proc()

Sleep

end GeSHi

使用嵌套命名 Type(避免使用类型别名和前向引用)解决两个主类型之间循环依赖的示例:

start GeSHi

vb
'' 使用类型别名和前向引用的两个相互依赖类型的示例:
'
'Type list As list_
'
'Type listnode
'    text As String
'    parent As list Ptr
'End Type
'
'Type list_
'    first As listnode Ptr
'    count As Integer
'End Type

'' 同样是两个相互依赖类型的示例,但改用嵌套命名类型:

Type list
    count As Integer
    Type listnode
        text As String
        parent As list Ptr
    End Type
    first As listnode Ptr
End Type

end GeSHi

检查访问语法和访问权限的示例:

start GeSHi

vb
Type UDT1
    Private:
        Dim As Integer I1 = 123
        Type UDT2
            Private:
                Dim As Integer I2 = 456
            Public:
                Declare Function returnI2() As Integer
        End Type
    Public:
        Type UDT3
            Private:
                Dim As Integer I3 = 789
            Public:
                Declare Function returnI3() As Integer
        End Type
        Declare Function returnI1() As Integer
        Dim As UDT2 t2
        Dim As UDT3 t3
End Type

Function UDT1.returnI1() As Integer
    Return This.I1
End Function

Function UDT1.UDT2.returnI2() As Integer
    Return This.I2
End Function

Function UDT1.UDT3.returnI3() As Integer
    Return This.I3
End Function

Dim As UDT1 t11

'Print t11.I1            '' error 202: Illegal member access
                         ''    I1 在 UDT1 的私有区域中

Print t11.returnI1()     '' OK,returnI1() 在 UDT1 的公有区域中

'Print t11.t2.I2         '' error 202: Illegal member access
                         ''    t2 在 UDT1 的公有区域中,但 I2 在 UDT2 的私有区域中

Print t11.t2.returnI2()  '' OK,t2 在 UDT1 的公有区域中,returnI2() 在 UDT2 的公有区域中

'Print t11.t3.I3         '' error 202: Illegal member access
                         ''    t3 在 UDT1 的公有区域中,但 I3 在 UDT3 的私有区域中

Print t11.t3.returnI3()  '' OK,t3 在 UDT1 的公有区域中,returnI3() 在 UDT3 的公有区域中
Print

'Dim As UDT1.UDT2 t21    '' error 202: Illegal member access
                         ''    UDT2 在 UDT1 的私有区域中

Dim As UDT1.UDT3 t31     '' OK,UDT3 在 UDT1 的公有区域中

'Print t31.I3            '' error 202: Illegal member access
                         ''    I3 在 UDT3 的私有区域中

Print t31.returnI3()     '' OK,returnI3() 在 UDT3 的公有区域中

Sleep

end GeSHi

嵌套命名类型用法示例。

这只是声明部分,但提供了一些值得指出的内容:

start GeSHi

vb
Type MemoryTable
    Private:
        '' 私有成员,仅在 MemoryTable 内部可见
        Const default_alignment = 16
        m_bytes_per_node As UInteger = 0
        m_nodes_per_chunk As UInteger = 0
        Type Chunk
            m_owner As MemoryTable Ptr
            m_nodes As UInteger
            m_prevChunk As Chunk Ptr
            m_data As Any Ptr
        End Type
        Declare Sub allocChunk()
        m_headChunk As Chunk Ptr = 0
    Protected:
        '' 受保护成员,在 MemoryTable 及其派生类型中可见
        Declare Constructor()
        Type Iterator
            Private:
                m_chunk As Chunk Ptr
                m_index As Integer
            Protected:
                Declare Constructor()
                Declare Constructor(ByVal table As MemoryTable Ptr)
                Declare Property item() As Any Ptr
            Public:
                Declare Property hasItem() As Boolean
                Declare Sub nextItem()
        End Type
        Declare Function newNode() As Any Ptr
    Public:
        '' 公有成员,可从类型外部访问
        Declare Constructor(ByVal bytes As UInteger, nodes As UInteger)
        Declare Destructor()
End Type

end GeSHi

参见

返回 目录

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