Skip to content

New 和 Delete


不同的 New(隐式/重载/表达式/定位)和 Delete(隐式/重载/语句)运算符,以及它们的所有数组版本 New[] 和 Delete[]

定义

用户可能会对不同的 New 和 Delete 运算符感到困惑(尽管文档通过多个不同页面加以区分):

  • 'Operator New Implicit'(用户不可访问)
  • Operator New Overload
  • 'Operator Delete Implicit'(用户不可访问)
  • Operator Delete Overload
  • Operator New Expression
  • Operator Delete Statement
  • Operator Placement New

'Operator New[] Implicit/Overload/Expression''Operator Delete[] Implicit/Overload/Statement''Operator Placement New[]' 的定义类似,它们只是前述运算符的(一维)数组版本(会对数组元素进行构造/析构循环)。

使用 '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(New/New[] 表达式运算符):

vb
'       NEW/NEW[] 表达式运算符
'                     V
'                     |
'              若存在则调用 >----------------------------------.
'                   否则                                      :
'                     v                                      v
'       (New/New[] 运算符隐式)          (New/New[] 运算符重载)
'                     :                                      :
'          基础内存分配                         用户内存分配代码
'                     :                                      :
'                     :<-------------------------------------'
'                     |
'                     |<-------------------------------------.
'                     |                                      :
'        数据字段初始化                                        :
'        对象字段构造                                          :
'           (VPTR 初始化)                                    :
'                     |                                      :
'              若存在则调用 >-------------.                :
'                   否则                    :                :
'                     v                     v                :
'                     :            (用户构造函数)            :
'                     :                     :                :
'                     :                 用户代码              :
'                     :                     :                :
'                     :<--------------------'                :
'                     |                                      :
'        若为数组版本 NEW[] 则循环 >------------------------'
'                   否则
'                     v
'                     |
'                     V

Operator Delete/Delete[] Statement(Delete/Delete[] 语句运算符):

vb
'     DELETE/DELETE[] 语句运算符
'                     V
'                     |
'                     |<-------------------------------------.
'                     |                                      :
'          (VPTR 重新初始化)                                :
'                     |                                      :
'              若存在则调用 >-------------.                :
'                   否则                    :                :
'                     v                     v                :
'                     :             (用户析构函数)            :
'                     :                     :                :
'                     :                 用户代码              :
'                     :                     :                :
'                     :<--------------------'                :
'                     |                                      :
'         对象字段析构                                         :
'                     |                                      :
'       若为数组版本 DELETE[] 则循环 >----------------------'
'                   否则
'                     v
'                     |
'              若存在则调用 >----------------------------------.
'                   否则                                      :
'                     v                                      v
'    (隐式 Delete/Delete[] 运算符)         (重载 Delete/Delete[] 运算符)
'                     :                                      :
'         基础内存释放                           用户内存释放代码
'                     :                                      :
'                     :<-------------------------------------'
'                     |
'                     V

Operator Placement New/New[](定位 New/New[] 运算符):

vb
'        定位 NEW/NEW[] 运算符
'                     V
'                     |
'                     |<-------------------------------------.
'                     |                                      :
'        数据字段初始化                                        :
'        对象字段构造                                          :
'           (VPTR 初始化)                                    :
'                     |                                      :
'              若存在则调用 >-----------------.                :
'                   否则                    :                :
'                     v                     v                :
'                     :             (用户构造函数)          :
'                     :                     :                :
'                     :                 用户代码              :
'                     :                     :                :
'                     :<--------------------'                :
'                     |                                      :
'        若为数组版本 NEW[] 则循环 >------------------------'
'                   否则
'                     v
'                     |
'                     V

示例

使用 New(Overload/Expression/Placement)和 Delete(Overload/Statement)运算符及其所有数组版本 New[] 和 Delete[] 的示例:

(用户可访问的全部 10 个 New 和 Delete 运算符):

start GeSHi

vb
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

end GeSHi

输出示例(64 位系统):

vb
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
vb
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"} => {"","","",""}

参见

返回 目录

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