異なる演算子
New (
Implicit/Overload/Expression/Placement) と
Delete (
Implicit/Overload/Statement)、およびその配列バージョン
New[] と
Delete[]
定義
異なる演算子
New と
Delete の間で、ユーザーの心理に混乱があるかもしれません(いくつかのページにわたって、それらの違いを区別する文書があるのですが):
- 'Operator New Implicit' (ユーザーはアクセスできません):
- これは、メモリを割り当てるだけの静的関数です(
Allocate と大差ありません)。
- 演算子 New 多重定義:
- これは、ユーザー定義型に対してのみ 'Operator New Implicit' を多重定義できるメンバー演算子(静的関数)です。
- したがって、ユーザーは、独自の動的メモリ割り当てプロセス部分を定義できます(暗黙的なデータ構築のための次のプロセス部分は、変更できません)。
- 'Operator Delete Implicit' (ユーザーはアクセスできません):
- 演算子 Delete 多重定義:
- これは、ユーザー定義型に対してのみ 'Operator Delete Implicit' を多重定義できる、メンバー演算子(静的サブ)です。
- したがって、ユーザーは独自のメモリ割り当て解除プロセス部分を定義できます(暗黙的なデータ破壊する、先のプロセス部分は変更できません)。
- 演算子 New 式:
- 'Operator New Implicit/Overload' (暗黙、または存在する場合は多重定義)を使ってメモリを割り当てます。
- そして、適切な型のオブジェクトのコンストラクターを呼び出します。そのオブジェクトに他のオブジェクト(埋め込み型または基本型として)が含まれている場合、それらのコンストラクターも呼び出されます。
- したがって、最終結果は、メモリの割り当てとオブジェクトの構築です。
- この演算子は、事前定義型(固定長文字列を除く)およびユーザー定義型に適用されます。
- 演算子 Delete 命令文:
- オブジェクトの正しい型のデストラクタを呼び出すことから始めます。そのオブジェクトに他のオブジェクト(埋め込み型または基本型として)が含まれている場合、それらのデストラクターも呼び出されます。
- そして、 'Operator Delete Implicit/Overload' (暗黙的、または存在する場合は多重定義)を使ってメモリの割り当てを解除します。
- したがって、最終結果は、オブジェクトが破壊され、メモリが解放されます。
- この演算子は、事前定義型(固定長文字列を除く)およびユーザー定義型に適用されます。
- 演算子 配置 New:
- 指定されたメモリアドレス(既に割り当てられている)でのみ、オブジェクトを構築します。 この演算子は、事前定義型(固定長文字列を除く)およびユーザー定義型に適用されます。
'Operator New[] Implicit/Overload/Expression',
'Operator Delete[] Implicit/Overload/Statement',
'Operator Placement New[]' の同様の定義。これは、前の演算子の(1次元)配列バージョンのみです(配列要素に対する 構築/破壊ループがあります)。
'Operator New Overload/Expression' で作成されたインスタンスは、
'Operator Delete Overload/Statement' で解放する必要があります。
'Operator New[] Overload/Expression' で作成されたインスタンス配列は、
'Operator Delete Overload/Statement' の配列バージョンである、
'Operator Delete[] Overload/Statement' で解放する必要があります。
ユーザーは、演算子の異なるバージョンを組み合わせて使うことはできません。
'Operator Placement New' で指定されたメモリアドレスで構築されたインスタンスは、アドレスの
'Operator Delete' で対称解放してはなりません(メモリは、
'Operator Placement New' 以外の方法で割り当てられているため)。
'Operator Placement New[]' で指定されたメモリアドレスで構築されたインスタンス配列は、アドレスの
'Operator Delete[]' で対称解放してはなりません(メモリは、
'Operator Placement New[]' 以外の方法で割り当てられているため)。
このような UDT インスタンスの場合、必要に応じて各インスタンスを破棄する適切な方法は、デストラクタが(暗黙的または明示的に)存在する場合は、メンバーアクセス演算子を使って、メンバーメソッドに関する構文で、デストラクタを呼び出すことです。
注: 演算子
'New[]' や
'Delete[]'(命令文/式/多重定義演算子の配列バージョン)および多重定義演算子
'Delete' でさえ、継承多型(サブタイプ多型)と直接互換性がありません。
(実際の型ではなく)サブ型ポインタを使うと、大部分は他の要素(最初の要素を除く)へのアクセスに失敗するからです。
アルゴリズム(ユーザー定義型に適用)
Operator New/New[] Expression:
' OPERATOR NEW/NEW[] EXPRESSION
' V
' |
' call if there is >----------------------------.
' else :
' v v
' (Operator New/New[] Implicit) (Operator New/New[] Overload)
' : :
' BASIC MEMORY ALLOCATION USER BODY for memory allocation
' : :
' :<-------------------------------------'
' |
' |<-------------------------------------.
' | :
' DATA FIELDS INITIALIZATION :
' OBJECT FIELDS CONSTRUCTION :
' (VPTR INITIALIZATION) :
' | :
' call if there is >-----------. :
' else : :
' v v :
' : (User Constructor) :
' : : :
' : USER BODY :
' : : :
' :<--------------------' :
' | :
' loop if array-version NEW[] >-----------------------'
' else
' v
' |
' V
Operator Delete/Delete[] Statement:
' OPERATOR DELETE/DELETE[] STATEMENT
' V
' |
' |<-------------------------------------.
' | :
' (VPTR REINITIALIZATION) :
' | :
' call if there is >-----------. :
' else : :
' v v :
' : (User Destructor) :
' : : :
' : USER BODY :
' : : :
' :<--------------------' :
' | :
' OBJECT FIELDS DESTRUCTION :
' | :
' loop if array-version DELETE[] >---------------------'
' else
' v
' |
' call if there is >----------------------------.
' else :
' v v
' (Operator Delete/Delete[] Implicit) (Operator Delete/Delete[] Overload)
' : :
' BASIC MEMORY DEALLOCATION USER BODY for memory deallocation
' : :
' :<-------------------------------------'
' |
' V
Operator Placement New/New[]:
' OPERATOR PLACEMENT NEW/NEW[]
' V
' |
' |<-------------------------------------.
' | :
' DATA FIELDS INITIALIZATION :
' OBJECT FIELDS CONSTRUCTION :
' (VPTR INITIALIZATION) :
' | :
' call if there is >-----------. :
' else : :
' v v :
' : (User Constructor) :
' : : :
' : USER BODY :
' : : :
' :<--------------------' :
' | :
' loop if array-version NEW[] >-----------------------'
' else
' v
' |
' V
例
演算子 New(多重定義/式/配置)と Delete(多重定義/命令文)、およびそれらの配列バージョン New[] と Delete[] を使う例:
(ユーザーがアクセスできる 10個の演算子 New と Delete のすべて):
Declare Sub printArray (ByRef label As String = "", array() As String)
Type UDT
Declare Constructor ()
Declare Destructor ()
Declare Operator New (ByVal size As UInteger) As Any Ptr ' Operator New Overload
Declare Operator New[] (ByVal size As UInteger) As Any Ptr ' Operator New[] Overload
Declare Operator Delete (ByVal buf As Any Ptr) ' Operator Delete Overload
Declare Operator Delete[] (ByVal buf As Any Ptr) ' Operator Delete[] Overload
Dim As String array (1 To 4)
End Type
Constructor UDT ()
Static As Integer n
Print " Constructor"
printArray(" init: @" & @This & " (descriptors) -> ", This.array())
For i As Integer = LBound(This.array) To UBound(This.array)
This.array(i) = Chr(Asc("a") + n + i - LBound(This.array))
Next i
printArray(" => ", This.array())
Print
n += UBound(This.array)- LBound(This.array) + 1
End Constructor
Destructor UDT ()
Print " Destructor"
printArray(" erase: @" & @This & " (descriptors) -> ", This.array())
Erase This.array
printArray(" => ", This.array())
Print
End Destructor
Operator UDT.New (ByVal size As UInteger) As Any Ptr
Print " Operator New Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.New[] (ByVal size As UInteger) As Any Ptr
Print " Operator New[] Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.Delete (ByVal buf As Any Ptr)
Print " Operator Delete Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Operator UDT.Delete[] (ByVal buf As Any Ptr)
Print " Operator Delete[] Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Print "Operator New Expression"
Dim As UDT Ptr pu1 = New UDT ' Operator New Expression
Print "Operator Delete Statement"
Delete pu1 ' Operator Delete Statement
Sleep
Print
Print "Operator New[] Expression"
Dim As UDT Ptr pu2 = New UDT[2] ' Operator New[] Expression
Print "Operator Delete[] Statement"
Delete[] pu2 ' Operator Delete[] Statement
Sleep
Dim As Byte buffer(1 To 256)
Dim As Any Ptr p = @buffer(1)
Print
Print "Operator Placement New"
Dim As UDT Ptr pu3 = New(p) UDT ' Operator Placement New
Print "User call of Destructor"
pu3->Destructor() ' User Call of Destructor
Sleep
Print
Print "Operator Placement New[]"
Dim As UDT Ptr pu4 = New(p) UDT[2] ' Operator Placement New[]
For i As Integer = 0 To 1
Print "User Call of Destructor"
pu4[i].Destructor() ' User Call of Destructor
Next i
Sleep
Sub printArray (ByRef label As String = "", array() As String)
Print label & "{";
For i As Integer = LBound(array) To UBound(array)
Print """" & array(i) & """";
If i < UBound(array) Then
Print ",";
End If
Next I
Print "}";
End Sub
出力例 (64-bit システムの場合):
Operator New Expression
Operator New Overload
memory allocation: 96 Bytes from @1728352
Constructor
init: @1728352 (descriptors) -> {"","","",""} => {"a","b","c","d"}
Operator Delete Statement
Destructor
erase: @1728352 (descriptors) -> {"a","b","c","d"} => {"","","",""}
Operator Delete Overload
memory deallocation: for @1728352
Operator New[] Expression
Operator New[] Overload
memory allocation: 200 Bytes from @1728352
Constructor
init: @1728360 (descriptors) -> {"","","",""} => {"e","f","g","h"}
Constructor
init: @1728456 (descriptors) -> {"","","",""} => {"i","j","k","l"}
Operator Delete[] Statement
Destructor
erase: @1728456 (descriptors) -> {"i","j","k","l"} => {"","","",""}
Destructor
erase: @1728360 (descriptors) -> {"e","f","g","h"} => {"","","",""}
Operator Delete[] Overload
memory deallocation: for @1728352
Operator Placement New
Constructor
init: @1375248 (descriptors) -> {"","","",""} => {"m","n","o","p"}
User call of Destructor
Destructor
erase: @1375248 (descriptors) -> {"m","n","o","p"} => {"","","",""}
Operator Placement New[]
Constructor
init: @1375248 (descriptors) -> {"","","",""} => {"q","r","s","t"}
Constructor
init: @1375344 (descriptors) -> {"","","",""} => {"u","v","w","x"}
User Call of Destructor
Destructor
erase: @1375248 (descriptors) -> {"q","r","s","t"} => {"","","",""}
User Call of Destructor
Destructor
erase: @1375344 (descriptors) -> {"u","v","w","x"} => {"","","",""}
参照