CONSTRUCTOR
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgConstructor
- 最后更新: 2022-08-15
在创建类或用户自定义类型时自动调用
语法
Type typename
declare Constructor ( )
declare Constructor ( [ byref | byval ] parameter as datatype [ = default ] [, ... ] )
End Type
Constructor typename ( [ parameters ] ) [ Export ]
statements
End Constructor参数
typename
Type 或 Class 的名称
说明
当创建用户自定义 Type 或 Class 变量时,会调用 Constructor 方法。
typename 是声明和定义 Constructor 方法的类型名称。在 Namespace 中使用时,typename 的名称解析遵循与过程相同的规则。
一个 Type 或 Class 可以有多个构造函数,但在创建用户自定义 Type 或 Class 变量时只会调用其中一个,具体调用哪个构造函数方法取决于变量初始化时匹配的 parameter 签名。
构造函数方法声明中可以有多个 parameter。
构造函数方法接收一个隐藏的 this 参数,其类型与 typename 相同。this 可选地用于访问要在 Constructor 方法中初始化的 Type 或 Class 的字段。
在声明全局或局部静态 typename 实例时,以及使用 New Expression 运算符动态分配 typename 时,会调用构造函数。请参阅下面的示例了解不同的构造函数语法。
拷贝 Constructor 是一种从现有对象初始化新对象的特殊构造函数。拷贝 Constructor 被调用的三种常见情况:在一条指令中实例化一个对象并用另一个对象初始化它时;按值传递对象时;从函数按值返回对象时(使用 Return x 语句)。
注意:当使用 Function = x(或 function_identifier = x)赋值从函数按值返回对象时,Constructor 仅在首次调用时调用一次,然后在每次赋值时调用 Let (Assign) 运算符。
如果浅层隐式拷贝构造函数不够用,则必须定义拷贝 Constructor。这种情况发生在对象管理动态分配的内存或其他需要特殊构造或复制的资源时(例如,如果成员指针指向动态分配的内存,隐式拷贝构造函数将仅执行隐式指针构造和值的复制,而不是分配内存然后执行数据复制)。
注意:即使定义了显式默认 Constructor,隐式拷贝构造函数也不会调用它。
拷贝 Constructor 不能按值声明其参数(要克隆的对象)。
支持嵌套类型中的构造函数链式调用。任何具有自己默认构造函数的字段会首先被调用。
通过在构造函数顶部使用关键字 Constructor(parameters),允许将相同类型的构造函数链式调用在一起。这会阻止编译器生成字段初始化代码(而是依赖链式构造函数来初始化所有内容)。
Constructor 也可以像其他成员方法(Sub)一样直接从 typename 实例调用,使用相同的语法,即使用成员访问运算符,例如 obj.Constructor(parameters)。特别是,this.Constructor(parameters) 不被视为相同类型构造函数的链式调用,在任何地方都允许(不仅限于构造函数顶部)。一般情况下,手动调用对象的构造函数是不安全的,因为不会调用 destructor,旧的对象状态(如果有的话)会在其旧成员未被销毁的情况下被覆盖,这可能导致内存/资源泄漏。
示例
面向初学者的简单构造函数示例:
start GeSHi
Type MyObj
Foo As Integer Ptr
'' Constructor to create our integer, and set its value.
Declare Constructor( ByVal DefVal As Integer = 0 )
'' Destroy our integer on object deletion.
Declare Destructor()
End Type
Constructor MyObj( ByVal DefVal As Integer = 0 )
Print "Creating a new integer in MyObj!"
Print "The Integer will have the value of: " & DefVal
Print ""
'' Create a pointer, and set its value to the one passed to the
'' Constructor.
This.Foo = New Integer
*This.Foo = DefVal
End Constructor
Destructor MyObj()
Print "Deleting our Integer in MyObj!"
Print ""
'' Delete the pointer we created in MyObj.
Delete This.Foo
This.Foo = 0
End Destructor
Scope
'' Create a MyObj type object
'' Send the value of '10' to the constructor
Dim As MyObj Bar = 10
'' See if the integer's been created. Print its value.
Print "The Value of our integer is: " & *Bar.Foo
Print ""
Sleep
End Scope
'' We've just gone out of a scope. The Destructor should be called now
'' Because our objects are being deleted.
Sleepend GeSHi
更高级的构造示例,展示了构造函数重载等特性:
start GeSHi
Type sample
_text As String
Declare Constructor ()
Declare Constructor ( a As Integer )
Declare Constructor ( a As Single )
Declare Constructor ( a As String, b As Byte )
Declare Operator Cast () As String
End Type
Constructor sample ()
Print "constructor sample ()"
Print
This._text = "Empty"
End Constructor
Constructor sample ( a As Integer )
Print "constructor sample ( a as integer )"
Print " a = "; a
Print
This._text = Str(a)
End Constructor
Constructor sample ( a As Single )
Print "constructor sample ( a as single )"
Print " a = "; a
Print
This._text = Str(a)
End Constructor
Constructor sample ( a As String, b As Byte )
Print "constructor sample ( a as string, b as byte )"
Print " a = "; a
Print " b = "; b
Print
This._text = Str(a) + "," + Str(b)
End Constructor
Operator sample.Cast () As String
Return This._text
End Operator
Print "Creating x1"
Dim x1 As sample
Print "Creating x2"
Dim x2 As sample = 1
Print "Creating x3"
Dim x3 As sample = 99.9
Print "Creating x4"
Dim x4 As sample = sample( "aaa", 1 )
Print "Values:"
Print " x1 = "; x1
Print " x2 = "; x2
Print " x3 = "; x3
Print " x4 = "; x4end GeSHi
拷贝构造函数示例:
start GeSHi
Type UDT
Dim As String Ptr p ''pointer to string
Declare Constructor () ''default constructor
Declare Constructor (ByRef rhs As UDT) ''copy constructor
Declare Destructor () ''destructor
End Type
Constructor UDT ()
This.p = CAllocate(1, SizeOf(String))
End Constructor
Constructor UDT (ByRef rhs As UDT)
This.p = CAllocate(1, SizeOf(String))
*This.p = *rhs.p
End Constructor
Destructor UDT ()
*This.p = ""
Deallocate This.p
End Destructor
Dim As UDT u0
*u0.p = "copy constructor exists"
Dim As UDT u = u0
*u0.p = "" ''to check the independance of the result copy with the object copied
Print *u.p
Sleepend GeSHi
方言差异
- 对象相关功能仅在 -lang fb 选项中受支持
与 QB 的差异
- FreeBASIC 新增特性
另请参阅
ClassConstructor(模块)New ExpressionDestructorType- 数据类型强制转换与转换
返回 目录