构造函数和析构函数

类、类实例、构造函数、析构函数

上文示例中有 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 释放,避免内存泄漏。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注