Type(UDT/别名/临时)和 Union
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgTypeUnion
- 最后更新: 2022-11-08
不同的关键字 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
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()
Sleepend GeSHi
使用嵌套命名 Type(避免使用类型别名和前向引用)解决两个主类型之间循环依赖的示例:
start GeSHi
'' 使用类型别名和前向引用的两个相互依赖类型的示例:
'
'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 Typeend GeSHi
检查访问语法和访问权限的示例:
start GeSHi
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 的公有区域中
Sleepend GeSHi
嵌套命名类型用法示例。
这只是声明部分,但提供了一些值得指出的内容:
start GeSHi
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 Typeend GeSHi
参见
返回 目录