类、类实例、构造函数、析构函数
上文示例中有 TAnimal 与子类 TDog。类只是一种类型,可理解为模板,类本身不存储任何数据,示例里的字段 MyInt: Integer 不会分配内存。
虽然通过类变量能让类自身持有数据,这里先不讨论,只讲普通字段的常规类。
想要给字段分配内存,必须创建类实例;创建实例要调用构造函数。
类的代码,如果你不去创建实例,那么它们如同不存在,不会被执行,不会给它们的变量分配内容,就好比一个模具一样,只有在使用它的时候才会分配内存。不用它的时候,它永远安安静静躺在哪里。
构造函数
- 特殊方法,用关键字
constructor声明; - 调用构造前系统先分配对象内存,再执行构造函数代码;
- 所有类都隐式继承
TObject,自带无参构造Create,不手动写也能用; - 自定义构造是初始化对象的最佳方式,可在构造里给字段赋初始值;
- 自定义构造通常也命名为
Create。
例子
program Demo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses SysUtils;
type
TAnimal = class
private
InternalStuff: TObject;
public
constructor Create;
destructor Destroy; override;
end;
constructor TAnimal.Create;
begin
inherited Create; // 开头先调用父构造
InternalStuff := TObject.Create;
Writeln('执行 TAnimal.Create 构造函数');
end;
destructor TAnimal.Destroy;
begin
Writeln('执行 TAnimal.Destroy 析构函数');
FreeAndNil(InternalStuff); // 释放内部子对象
inherited Destroy; // 末尾调用父析构
end;
var
C: TAnimal;
begin
C := TAnimal.Create;
try
// 使用对象
finally
FreeAndNil(C); // 自动调用 Destroy 析构
end;
end.
运行
D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
38 lines compiled, 0.1 sec, 68672 bytes code, 4260 bytes data
D:\fpcdemo>mydemo
执行 TMyClass.Create 构造函数
执行 TMyClass.Destroy 析构函数Code language: CSS (css)
InternalStuff 是类内部持有的子对象。 构造时创建,析构时必须 FreeAndNil 释放,避免内存泄漏。
