FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgTypeIterators

目次→教本→プログラマーのための案内Type (UDT/Alias/Temporary) and Union←オリジナル・サイト

Type (UDT/Alias/Temporary) と Union 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

さまざまなキーワード Type (UDT), Type (Alias), Type (Temporary), Union

定義
TypeUnion という異なるキーワードが、ユーザーの頭の中で混同されている可能性があります(ドキュメントのいくつかのページで、それぞれを互いに区別していますが):
型/共用体構造の複雑さのレベル:
- 自明な構造: メンバー手続きを持たない、名前付きまたは匿名の構造(間接的に直接)。
- 複雑な構造体: メンバー 手続きを持つ名前付き構造体 (直接的または間接的)。
- 拡張構造: 別の名前付き構造体から継承する名前付き構造体。

型/共用体構造は、別の型/共用体構造内にネストすることもできます:
- 入れ子になった名前付き型: 別の名前付き型/共用体構造内に入れ子になっている名前付き型。
- 入れ子になった匿名型: 別の名前付きまたは匿名共用体構造内に入れ子になっている匿名型。
- 入れ子になった名前付き共用体: 別の名前付き型/共用体構造内に入れ子になっている名前付き共用体。
- 入れ子になった匿名共用体: 別の名前付きまたは匿名型構造内にネストされた匿名共用体。

型 (エイリアス) 宣言は、型/共用体構造内に入れ子にすることもできます。
- 入れ子にされた型(エイリアス)宣言では、型/共用体内で、場所のアクセス権に従って内部エイリアスを宣言できます。

記述
ネストされた名前付き型/共用体の主な目的は次のとおりです:
- 型と共用体の間の関係を理解可能な方法で表現できるようにするため。
- このような型やユニオンは、独自の名前空間を持ち、その中で関連するシンボルを整理し、型に対してのみ可視性アクセス(Public/Protected/Private)を提供し、メンバーへのアクセスをよりきめ細かく制御できるようにします。
- 型/共用体の間に循環依存関係がある場合、入れ子になった名前付き型/共用体を使用することで、Type(Alias)の使用や前方参照を避けることができます。

ネストされた名前付き型/共用体がない場合:
- Type/Union 間で関係を表現することは可能ですが、すべての Type/Union がパブリックにアクセス可能でなければならないというデメリットがあります。
- Namespace の使用は、可視性の範囲を整理するのに役立ちますが、問題は、*すべての*型/ユニオンが可視でなければならないことに変わりはありません。
- このため、ユーザー(または作成者自身)が意図しない方法で Type/Union を使用してしまい、有効ではあるがエラーを起こしやすいコードを作成する可能性があります。
- この問題は、Type/Union を前方宣言で非表示にしたり(Type (Alias))、プライベート・シンボルを別のモジュールに入れることで軽減できますが、コードが断片化することで新たな問題が発生します。

匿名型 (または共用体):
- 名前がなく、名前で参照できません。
- Named Union (または Type) または別の Anonymous Union (または Type) 内にだけネストされて表示される場合があります。
- ネストした構造体内のフィールドを、別々のメモリ位置(Nested Type)または重複するメモリ位置(Nested Union)に宣言します。
- フィールドを参照できます。
- 静的メンバーや手続き宣言を (直接的にも間接的にも) 含めることはできません => 自明な構造。

名前付き型 (または共用体):
- フィールド、変数、パラメーター、配列などのデータ型を宣言するために参照できる名前があります。
- 単独で、または他の名前付き型(またはUnion)の中にネストして表示することができます。
- Type (または Union) の宣言のみ。
- ネストする構造内でフィールドを宣言しないため、サイズが追加されません。
- 静的メンバーまたは手続き宣言を (直接的または間接的に) 含めることができます => 自明/複雑な構造。

Type/Union 構造と(対)スコープの場所の、複雑さのレベル:
- 自明な構造: グローバル/名前空間/ネストされたスコープ、またはローカル スコープ内 (Scope や Sub など) で宣言できる、名前付きまたは匿名型/共用体。
- 複雑な構造: グローバル/ネームスペース/ネストされたスコープで宣言し、グローバル/ネームスペース スコープで定義する必要がある、名前付きタイプ/ユニオン。
- 拡張構造: Base のスコープ (現在は Base と同じスコープ) に対する可視性を持つスコープで宣言された名前付き Type/Union。

メイン構造 (Type/Union) は常に名前付きでなければならず、他の (ネストされた) 構造は匿名または名前付きにすることができます。
名前付き型/共用体で実行できるほとんどすべてのことは、継承機能 (ベースまたは派生として) を含め、ネストされた名前付き型/共用体でも実行できます。
ネストされた匿名型/共用体は、手続き メンバーまたは静的データ メンバーを持つことはできません (ローカル スコープ内の名前付き型/共用体と同じ制限)。

例: 'Named Type' <- 'Nested Anonymous Union' <- 'Nested Anonymous Type':
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

ネストされた名前付き型を使って、2 つの主要な型間の循環的な依存関係を解決する例 (型エイリアスの使用と前方参照を避けるため):
'' example of two dependent types, with a type alias and a forward referencing:
'
'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



'' same example of two dependent types, but with simply one of them a Nested Named Type:

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

アクセス構文とアクセス権を確認する例:
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 is in the private section of UDT1

Print t11.returnI1()     '' OK, returnI1() is in the public section of UDT1

'Print t11.t2.I2         '' error 202: Illegal member access
                         ''    t2 is in the public section of UDT1, but I2 is in the private section of UDT2

Print t11.t2.returnI2()  '' OK, t2 is in the public section of UDT1, and returnI2() is in the public section of UDT2

'Print t11.t3.I3         '' error 202: Illegal member access
                         ''    t3 is in the public section of UDT1, but I3 is in the private section of UDT3

Print t11.t3.returnI3()  '' OK, t3 is in the public section of UDT1, and returnI3() is in the public section of UDT3
Print

'Dim As UDT1.UDT2 t21    '' error 202: Illegal member access
                         ''    UDT2 is in the private section of UDT1

Dim As UDT1.UDT3 t31     '' OK, UDT3 is in the public section of UDT1

'Print t31.I3            '' error 202: Illegal member access
                         ''    I3 is in the private section of UDT3

Print t31.returnI3()     '' OK, returnI3() is in the public section of UDT3

Sleep

ネストされた名前付き型でできることの例
これは宣言の部分だけですが、指摘に値するいくつかの点をあげています:
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:
        '' 型の外部から見える public メンバー
        Declare Constructor(ByVal bytes As UInteger, nodes As UInteger)
        Declare Destructor()
End Type

参照
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2022-11-08 04:26:55
日本語翻訳:WATANABE Makoto、原文著作者:fxm

ホームページのトップに戻る

表示-非営利-継承