程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 《delphi高手突破》節選二

《delphi高手突破》節選二

編輯:Delphi

構造函數與異常

這個話題在C++社區中經常會被提起,而在Delphi社區中似乎從來沒有人注意過。也許由於語言的特性,使得Delphi程序員不必關心這個問題。但我想Delphi程序員也應該對該問題有所了解,知道語言為我們提供了什麼而使得我們如此輕松,不必理會它。正所謂“身在福中須知福”。 我們知道,類的構造函數是沒有返回值的,如果構造函數構造對象失敗,不可能依靠返回錯誤代碼。那麼,在程序中如何標識構造函數的失敗呢?最“標准”的方法就是:拋出一個異常。 構造函數失敗,意味著對象的構造失敗,那麼拋出異常之後,這個“半死不活”的對象會被如何處理呢? 在此,我想讀著有必要先對C++對這種情況的處理方式先有個了解。 在C++中,構造函數拋出異常後,析構函數不會被調用。這種做法是合理的,因為此時對象並沒有被完整構造。 如果構造函數已經做了一些諸如分配內存、打開文件等操作的話,那麼C++類需要有自己的成員來記住做過哪些動作。當然,這樣做對於類的實現者來說非常麻煩,因此一般C++類的實現者都避免在構造函數中拋出異常(可以提供一個諸如Init和UnInit的成員函數,由構造函數或類的客戶去調用它們,以處理初始化失敗的情況)。而每一本C++的經典著作所提供的方案是使用智能指針(STL的標准類auto_ptr)。 在Object Pascal中,這個問題變得非常的簡單,程序員不必為此大費周折。如果Object Pascal的類在構造函數中拋出異常,編譯器會自動調用類的析構函數(由於析構函數不允許被重載,可以保證只有唯一一個析構函數,因此編譯器不會迷惑於多個析構函數之中)。析構函數中一般會析構成員對象,而Free()方法保證了不會對nil對象(即尚未被創建的成員對象)調用析構函數,因此在使得代碼簡潔優美的前提下,又保證了安全。 type MyClass = class private FStr : PChar; // 字符串指針 public constructor Create(); destructor Destroy(); override; end;   constructor MyClass.Create(); begin FStr := StrAlloc(10); // 構造函數中為字符串指針分配內存 StrCopy(FStr, 'ABCDEFGHI'); raise Exception.Create('error'); // 拋出異常,沒有理由,呵呵 end;   destructor A.Destroy(); begin StrDispose(FStr); // 析構函數中釋放內存 WriteLn('Free Resource'); end;   var Obj : TMyClass; i : integer; begin try Obj := TMyClass.Create(); Obj.Free(); WriteLn('Succeeded'); except Obj := nil; WriteLn('Failed'); end;   Read(i); // 暫停屏幕,以便觀察運行結果 end.   在這段代碼中,構造函數拋出異常,執行的結果是: Free Resource Failed 此時的“Free Resource”輸出是由編譯器自動調用析構函數所產生的。 因此,如果類的說明文檔或類的作者告知你,類的構造函數可能會拋出異常,那就要記得用try…except包住它!C++與Object Pascal對於構造函數拋出異常後的不同處理方式,其實正是兩種語言的設計思想的體現。C++秉承C的風格,注重效率,一切交給程序員來掌握,編譯器不作多余動作。Object Pascal繼承Pascal的風格,注重程序的美學意義,編譯器幫助程序員完成復雜的工作。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved