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;
Create,可重載(不同參數)。inherited Create(或 inherited)初始化父類部分,即使父類為 TObject。inherited Create(編譯器自動插入),但明確呼叫更清晰。Self),不可自定義返回類型。Destroy,必須標記 override 以確保多態銷毀。inherited Destroy(或 inherited)。Destroy,改用 Free(內部檢查 nil)。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 |
直接呼叫 Destroy | nil 物件導致 AV | 改用 Free |
| 資源獲取後異常未釋放 | 記憶體/句柄洩漏 | try..finally..Free |
IInterface 的類別,_AddRef/_Release 控制生命週期,Destroy 在引用計數歸零時由 _Release 呼叫。Free,否則雙重釋放。FRefCount := 1(或繼承 TInterfacedObject 自動處理)。掌握建構子/解構子的正確調用順序、參數模式與異常安全釋放模式,是編寫健壯 Delphi 物件導向程式的基礎功夫。