构造函数和析构函数(基础)
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgCtorsDtors
- 最后更新: 2019-09-05
负责对象的创建和销毁。
概述
构造函数和析构函数分别负责创建和销毁对象。一般来说,构造函数给对象赋予初始状态,即给对象的成员数据赋予有意义的值。析构函数执行相反的功能;它们确保对象拥有的任何资源都被正确释放。
简单地说,构造函数是在创建对象时被调用的特殊成员过程,析构函数是在销毁对象时被调用的特殊成员过程。无论是使用 Dim 或 New Expression/Delete Statement 关键字显式创建或销毁对象,还是通过按值将对象传递给过程或通过对象超出作用域而隐式发生,构造函数和析构函数都由编译器自动调用。
声明
构造函数和析构函数像成员过程一样声明,但使用 Constructor 关键字代替 Sub 或 Function,且没有名称。类似地,它们仅用其声明所在的 Type 或 Class 的名称来定义。
Type 或 Class 可以有多个构造函数,但只能有一个析构函数。
默认构造函数
默认构造函数是没有参数或所有参数都有默认值的构造函数。当使用 Dim、Redim 或 New[] 表达式关键字定义但未初始化对象,或将其作为数组的一部分创建时,将调用它们。下面示例中声明的第一个构造函数是默认构造函数。
复制构造函数
复制构造函数是当从同类型的另一个对象(或可以转换为该类型的对象)创建或克隆对象时调用的构造函数。这在使用另一个对象初始化对象时显式发生,或在按值将对象传递给过程时隐式发生。复制构造函数的声明具有一个参数:通过引用传递的同类型对象。
复制构造函数只在创建和初始化对象实例时调用。对对象的赋值由 成员运算符 let 处理。
调用构造函数
与其他成员过程不同,构造函数通常不直接从对象实例调用。相反,在 Dim 语句中使用带或不带初始化器指定构造函数,或在 New Expression 语句中带或不带参数指定。
为对象指定初始化器时,使用类型名称后跟所需参数。
start GeSHi
Type foo
'' Declare a default ctor, copy ctor and normal ctor
Declare Constructor
Declare Constructor (ByRef As foo)
Declare Constructor (As Integer)
'' Declare a destructor
Declare Destructor
ints As Integer Ptr
numints As Integer
End Type
'' Define a constructor that creates 100 integers
Constructor foo
ints = New Integer(100)
numints = 100
End Constructor
'' Define a constructor that copies the integers from another object
Constructor foo (ByRef x As foo)
ints = New Integer(x.numints)
numints = x.numints
End Constructor
'' Define a constructor that creates some integers based on a parameter
Constructor foo (n As Integer)
ints = New Integer(n)
numints = n
End Constructor
'' Define a destructor that destroys those integers
Destructor foo
Delete[] ints
End Destructor
Scope
'' calls foo's default ctor
Dim a As foo
Dim x As foo Ptr = New foo
'' calls foo's copy ctor
Dim b As foo = a
Dim y As foo Ptr = New foo(*x)
'' calls foo's normal ctor
Dim c As foo = foo(20)
Dim z As foo Ptr = New foo(20)
'' calls foo's dtor
Delete x
Delete y
Delete z
End Scope '' <- a, b and c are destroyed here as wellend GeSHi
编译器提供的构造函数和析构函数
如果没有为 Type 或 Class 声明复制构造函数,编译器将提供一个。如果没有声明任何构造函数,编译器也会提供一个默认构造函数。
编译器提供的默认构造函数将成员数据初始化为默认值,即数值和指针成员设置为零(0),对象成员进行默认构造。编译器声明的复制构造函数对一个类型的所有成员数据进行浅复制到另一个类型:数值和指针类型用被复制对象中对应的数据成员初始化,对象成员从其对应的对象成员进行复制构造。这意味着动态资源(例如指针数据成员指向的内存)不会被复制;只复制地址。因此,如果一个对象拥有某个资源,即它负责该资源的创建和销毁,则编译器生成的复制构造函数将不够用。
如果未声明析构函数,编译器会生成一个。这个析构函数调用对象成员的析构函数,对数值和指针类型不做任何操作。同样,如果一个对象拥有动态资源,则编译器生成的析构函数将不够用,因为对象销毁时资源不会被释放。
这通常被称为"三法则":如果一个对象需要自定义复制构造函数、赋值运算符或析构函数,很可能它三者都需要。
参见
Constructor,Destructor- 构造函数、'=' 赋值运算符和析构函数(高级,第 #1 部分)
- 构造函数、'=' 赋值运算符和析构函数(高级,第 #2 部分)
返回 目录