引發和處理異常
要創建一個異常對象,應在raise語句中調用異常類的構造器,如
raise EMathError.Create;
一般情況下,raise具有如下形式
raise object at address
這里的object和at address都是可選的。如果object被省略,那么語句將再引發當前異常(見再引發異常)。當某個address被指定時,通常是一個指向過程或函數的指針;利用該選項可以從堆棧中較早的點(與錯誤實際發生的點比較)引發異常。
異常被引發,即異常在raise語句中被引用時,異常由特殊的異常處理邏輯來管理。通常,raise語句從不返回控制。取而代之的是,它把控制傳遞到最內層的異常處理程序,該處理程序能處理給定類的異常。(最內層的處理程序就是一個try...except塊中尚未退出的最近入口。)
例如,下面的函數把一個串轉換為整數,如果結果在指定范圍之外則引發一個ERangeError異常。
function StrToIntRange(const S: string; Min, Max: Longint): Longint;
begin
Result := StrToInt(S); // StrToInt函數在SysUtils單元中定義
if (Result < Min) or (Result > Max) then
raise ERangeError.CreateFmt(
'%d is not within the valid range of %d..%d',
[Result, Min, Max]);
end;
可以注意到,在raise語句中調用的是CreateFmt方法。Exception類及其后裔類擁有特殊的構造器,為創建異常消息和環境ID提供多於一種途徑。
引發的異常在其處理后自動銷毀,決不要試圖人為銷毀一個引發的異常。
注意:單元的初始化節中引發異常不能達到預期的結果。一般的異常支持來自SysUtils單元,在異常支持可用之前該單元必需被初始化。如果一個異常在初始化過程中發生,那么包括SysUtils單元在內所有初始化過的單元,都會被結束(finalized)並且異常被再引發。這時異常被捕獲和處理,通常通過中斷程序。