首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 建構子與解構子完整指南:Create/Destroy、繼承鏈調用、參數傳遞與資源管理

     編輯:Delphi

Delphi 物件生命週期由建構子(constructor)與解構子(destructor)管理。本文通過 TPerson 類別完整演示帶參數建構子、重寫解構子、inherited 調用規則、Free 機制與異常安全模式。

類別定義單元

unit Person;

interface

uses Dialogs;

type
  TPerson = class(TObject)
  private
    FName: string;
    FAge: Integer;
  public
    constructor Create(StrName: string; IntAge: Integer);
    destructor Destroy; override;
    function GetName: string;
    function GetAge: Integer;
    procedure SetName(const StrName: string);
    procedure SetAge(const IntAge: Integer);
  end;

implementation

{ TPerson }

constructor TPerson.Create(StrName: string; IntAge: Integer);
begin
  inherited Create;  { 必須呼叫:參數簽名不同,不能省略 }
  FName := StrName;
  if IntAge < 0 then IntAge := 0;
  FAge := IntAge;
end;

destructor TPerson.Destroy;
begin
  ShowMessage(FName + '向你問好!');
  // inherited Destroy;  { 完整寫法 }
  inherited;           { 省略同名方法調用 }
end;

function TPerson.GetName: string;
begin
  Result := FName;
end;

function TPerson.GetAge: Integer;
begin
  Result := FAge;
end;

procedure TPerson.SetName(const StrName: string);
begin
  FName := StrName;
end;

procedure TPerson.SetAge(const IntAge: Integer);
begin
  if IntAge < 0 then FAge := 0 else FAge := IntAge;
end;

end.

測試代碼

uses Person;

procedure TForm1.Button1Click(Sender: TObject);
var
  PersonOne: TPerson;
begin
  PersonOne := TPerson.Create('wy', 99);
  try
    ShowMessage('姓名:' + PersonOne.GetName + '; 年齡:' + IntToStr(PersonOne.GetAge));
    PersonOne.SetName('萬一');
    PersonOne.SetAge(100);
    ShowMessage('姓名:' + PersonOne.GetName + '; 年齡:' + IntToStr(PersonOne.GetAge));
  finally
    PersonOne.Free;  { 輸出:萬一向你問好! }
  end;
end;

核心規則詳解

1. 建構子

  • 名稱慣例為 Create,可重載(不同參數)。
  • 必須呼叫 inherited Create(或 inherited)初始化父類部分,即使父類為 TObject。
  • 若參數與父類建構子相同,可省略 inherited Create(編譯器自動插入),但明確呼叫更清晰。
  • 返回類型隱含為類別實例(Self),不可自定義返回類型。

2. 解構子

  • 名稱慣例為 Destroy,必須標記 override 以確保多態銷毀。
  • 先釋放自身資源,最後呼叫 inherited Destroy(或 inherited)。
  • 絕不直接呼叫 Destroy,改用 Free(內部檢查 nil)。

3. Free 機制

procedure TObject.Free;
begin
  if Self <> nil then Destroy;
end;
  • 安全處理 nil 參考,防止重複釋放崩潰。
  • 建議搭配 try..finally 或 FreeAndNil(SysUtils)。

異常安全模式

var
  Obj: TMyClass;
begin
  Obj := TMyClass.Create;
  try
    Obj.DoSomething;  { 可能拋出異常 }
  finally
    Obj.Free;         { 保證釋放 }
  end;
end;

或使用 FreeAndNil(Obj)(同時置 nil,防止後續誤用)。

建構子參數傳遞模式

模式範例適用場景
無參數constructor Create; override;預設初始化,元件流式讀取必需
單參數constructor Create(AOwner: TComponent);VCL 控件標準
多參數constructor Create(const Name: string; Age: Integer);業務物件依賴注入
工廠方法class function CreateNew(...): TMyClass;複雜構造邏輯、單例、池化

常見錯誤與修正

錯誤後果修正
解構子缺少 override父類變數 Free 時不調用子類 Destroy加上 override
建構子未呼叫 inherited Create父類字段未初始化,虛擬方法表不完整首行加 inherited Create
直接呼叫 Destroynil 物件導致 AV改用 Free
資源獲取後異常未釋放記憶體/句柄洩漏try..finally..Free

進階:介面參考計數與建構子/解構子

  • 實作 IInterface 的類別,_AddRef/_Release 控制生命週期,Destroy 在引用計數歸零時由 _Release 呼叫。
  • 此類類別不可混用 Free,否則雙重釋放。
  • 建構子應初始化 FRefCount := 1(或繼承 TInterfacedObject 自動處理)。

掌握建構子/解構子的正確調用順序、參數模式與異常安全釋放模式,是編寫健壯 Delphi 物件導向程式的基礎功夫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved