青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

幽幽
 
posts - 51,  comments - 28,  trackbacks - 0

再談異常――談C++與Object Pascal中的構造函數與異常

作者:Nicrosoft(nicrosoft@sunistudio.com) 2001.9.15
個人主頁:http://www.sunistudio.com/nicrosoft/
東日文檔:http://www.sunistudio.com/asp/sunidoc.asp

  我們知道,類的構造函數是沒有返回值的,如果構造函數構造對象失敗,不可能依靠返回錯誤代碼。那么,在程序中如何標識構造函數的失敗呢?最“標準”的方法就是:拋出一個異常。

  構造函數失敗,意味著對象的構造失敗,那么拋出異常之后,這個“半死不活”的對象會被如何處理呢?這就是本文的主題。

在C++中,構造函數拋出異常后,析構函數不會被調用。這是合理的,因為此時對象并沒有被完整構造。也就是說,如果構造函數已經做了一些諸如分配內存、 打開文件等操作的話,那么類需要有自己的成員來記住做過哪些動作。在C++中,經典的解決方案是使用STL的標準類auto_ptr,這在每一本經典 C++著作中都有介紹,我在這里就不多說了。在這里,我想再介紹一種“非常規”的方式,其思想就是避免在構造函數中拋出異常。我們可以在類中增加一個 Init(); 以及 UnInit();成員函數用于進行容易產生錯誤的資源分配工作,而真正的構造函數中先將所有成員置為NULL,然后調用 Init(); 并判斷其返回值(或者捕捉 Init()拋出的異常),如果Init();失敗了,則在構造函數中調用 UnInit(); 并設置一個標志位表明構造失敗。UnInit()中按照成員是否為NULL進行資源的釋放工作。示例代碼如下:
class A
{
private:
 char* str;
 int failed;

public:
 A();
 ~A();
 int Init();
 int UnInit();
 int Failed();
};

A::A()
{
 str = NULL;
 try
 {
  Init();
  failed = 0;
 }
 catch(...)
 {
  failed = 1;
  UnInit();
 }
}

A::~A()
{
 UnInit();
}

int A::Init()
{
 str = new char[10];
 strcpy(str, "ABCDEFGHI");
 throw 10;

 return 1;
}

int A::UnInit()
{
 if (!str)
 {
  delete []str;
  str = NULL;
 }

 printf("Free Resource

");
 return 1;
}

int A::Failed()
{
 return failed;
}

int main(int argc, char* argv[])
{
 A* a = new A;
 if ( a->Failed() )
  printf("failed

");
 else
  printf("succeeded

");

 delete a;

 getchar();
 return 0;
}

  你會發現,在int A::Init()中包含了throw 10;的代碼(產生一個異常,模擬錯誤的發生),執行結果是:
  Free Resource
  failed
  Free Resource
  雖然 UnInit();被調用了兩次,但是由于UnInit();中做了判斷(if (!str)),因此不會發生錯誤。而如果沒有發生異常(去掉 int A::Init()中的throw 10;代碼),執行結果是:
  Succeeded
  Free Resource
  和正常的流程沒有任何區別。

在Object Pascal(Delphi/VCL)中,這個問題就變得非常的簡單了,因為 OP 對構造函數的異常的處理與C++不同,在Create時拋出異常后,編譯器會自動調用析構函數Destroy,并且會判斷哪些資源被分配了,實行自動回 收。因此,其代碼也變得非常簡潔,如下:
type
  A = class
  private
  str : PChar;
  public
  constructor Create();
  destructor Destroy(); override;
  end;

constructor A.Create();
begin
  str := StrAlloc(10);
  StrCopy(str, 'ABCDEFGHI');
  raise Exception.Create('error');
end;

destructor A.Destroy();
begin
  StrDispose(str);
  WriteLn('Free Resource');
end;

var oa : A;
  i : integer;
begin
  try
      oa := A.Create();
      WriteLn('Succeeded');
      oa.Free();
  except
      oa := nil;
      WriteLn('Failed');
  end;

  Read(i);
end.

  在這段代碼中,如果構造函數拋出異常(即Create中含有raise Exception.Create('error');),執行的結果是:
  Free Resource
  Failed
  此時的“Free Resource”輸出是由編譯器自動調用析構函數所產生的。而如果構造函數正常返回(即不拋出異常),則執行結果是:
  Succeeded
  Free Resource
  此時的“Free Resource”輸出是由 oa.Free()的調用產生的。

綜上,C++與Object Pascal對于構造函數拋出異常后的不同處理方式,其實正是兩種語言的設計思想的體現。C++秉承C的風格,注重效率,一切交給程序員來掌握,編譯器不 作多余動作。Object Pascal繼承Pascal的風格,注重程序的美學意義(不可否認,Pascal代碼是全世界最優美的代碼),編譯器幫助程序員完成復雜的工作。兩種語 言都有存在的理由,都有存在的必要!而掌握它們之間的差別,能讓你更好地控制它們,達到自由的理想王國。


posted on 2009-05-20 00:42 幽幽 閱讀(670) 評論(1)  編輯 收藏 引用 所屬分類: 雜集

FeedBack:
# re: 再談異常――談C++與Object Pascal中的構造函數與異常
2009-05-20 09:56 | 陳梓瀚(vczh)
C++更經典的方案就是,在能夠拋出異常的構造函數里面,不要new指針,非要的話用智能指針……這樣固有的機制可以讓你連析構函數都不用寫。  回復  更多評論
  

<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用鏈接

留言簿(6)

隨筆分類(35)

隨筆檔案(51)

文章分類(3)

文章檔案(3)

相冊

我的鏈接

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            麻豆freexxxx性91精品| 亚洲人被黑人高潮完整版| 国产精品私人影院| 亚洲成人在线网站| 久久激情中文| 亚洲免费在线播放| 国产精品国产成人国产三级| 亚洲激情亚洲| 欧美插天视频在线播放| 香蕉国产精品偷在线观看不卡| 欧美视频亚洲视频| 中文av一区特黄| 亚洲毛片在线观看| 欧美精品在线免费观看| 91久久久在线| 久久精品人人做人人爽| 一区二区三区国产| 欧美日韩免费一区| 亚洲午夜电影| 9色porny自拍视频一区二区| 欧美日韩亚洲在线| 一区二区三区黄色| 一区二区免费在线播放| 国产精品黄视频| 欧美一区二粉嫩精品国产一线天| 亚洲永久精品大片| 国产日韩在线播放| 久久亚洲美女| 免费av成人在线| 亚洲日韩中文字幕在线播放| 亚洲精品日韩精品| 国产精品色在线| 久久久国产午夜精品| 欧美jjzz| 久久国产乱子精品免费女| 亚洲人成网站999久久久综合| 久久成人精品视频| 黄网站色欧美视频| 亚洲福利专区| 欧美日韩一区二区在线播放| 欧美亚洲在线观看| 久久久www成人免费毛片麻豆| 亚洲国产精品视频| 亚洲裸体视频| 国产午夜精品美女毛片视频| 欧美成人精品在线播放| 欧美屁股在线| 久久精品av麻豆的观看方式| 蜜臀99久久精品久久久久久软件| 在线一区视频| 久久国产精品99国产| 午夜精品福利在线| 欧美一区二区三区免费观看| 在线观看国产欧美| 日韩视频中文字幕| 国内精品免费在线观看| 亚洲国产精品成人一区二区| 国产精品家庭影院| 欧美黄色网络| 国产精品护士白丝一区av| 久久久蜜桃一区二区人| 欧美日韩第一区日日骚| 久久久久久夜精品精品免费| 欧美巨乳在线观看| 理论片一区二区在线| 欧美视频福利| 亚洲第一网站| 国产一区二区成人久久免费影院| 亚洲韩国日本中文字幕| 国产一区二区三区自拍 | 亚洲综合社区| 久久亚洲不卡| 欧美伊人久久久久久午夜久久久久| 狂野欧美激情性xxxx欧美| 亚洲欧美偷拍卡通变态| 欧美激情中文不卡| 欧美成人一区二免费视频软件| 亚洲毛片一区| 亚洲欧美日本另类| 久久亚洲影音av资源网| 亚洲欧美成人网| 久久综合色婷婷| 欧美一区二区三区久久精品| 老司机精品久久| 欧美一区激情视频在线观看| 欧美精品国产一区| 狼人社综合社区| 国产伦精品一区二区三区免费迷| 亚洲欧洲日产国码二区| 韩国在线一区| 午夜精品久久久99热福利| 一本久道久久综合中文字幕| 老司机久久99久久精品播放免费| 久久高清国产| 欧美午夜视频一区二区| 久久精品国产精品亚洲| 男男成人高潮片免费网站| 欧美有码在线视频| 国产精品推荐精品| 亚洲视屏一区| 亚洲免费影视第一页| 欧美日韩另类在线| 91久久精品一区二区三区| 亚洲福利免费| 另类酷文…触手系列精品集v1小说| 久久免费一区| 国自产拍偷拍福利精品免费一| 欧美影片第一页| 久久蜜桃香蕉精品一区二区三区| 国产无一区二区| 久久国产精品99精品国产| 久久人体大胆视频| 亚洲国产高清aⅴ视频| 欧美α欧美αv大片| 亚洲日本久久| 亚洲欧美国产77777| 国产精品亚洲网站| 久久成人免费日本黄色| 亚洲高清不卡在线| 在线观看欧美日本| 久久综合色播五月| 亚洲激情电影在线| 亚洲已满18点击进入久久| 国产欧美精品xxxx另类| 久久久久成人网| 91久久国产综合久久91精品网站| 亚洲少妇一区| 国产在线视频欧美一区二区三区| 蜜桃av一区二区| 一本色道久久综合狠狠躁的推荐| 性亚洲最疯狂xxxx高清| 伊人成人在线| 国产日韩精品在线观看| 亚洲视频自拍偷拍| 欧美一区二区视频观看视频| 国产主播一区二区| 猛男gaygay欧美视频| 亚洲视频中文字幕| 免费亚洲电影| 亚洲欧美文学| 亚洲人成在线免费观看| 国产精品视频在线观看| 免费在线观看成人av| 亚洲一区免费在线观看| 欧美激情精品久久久久| 久久av免费一区| 亚洲美女尤物影院| 好吊妞这里只有精品| 欧美色图首页| 欧美aaa级| 久久精品视频免费| 亚洲摸下面视频| 亚洲三级电影全部在线观看高清| 久久国产精品色婷婷| 在线一区二区三区做爰视频网站 | 久久精品国产99国产精品| 亚洲人成亚洲人成在线观看| 久久久99国产精品免费| 国产精品99久久久久久久久| 亚洲国产精品成人| 国产综合精品| 国产毛片精品国产一区二区三区| 欧美日韩aaaaa| 欧美成人一二三| 久久久中精品2020中文| 午夜视频在线观看一区| 亚洲私拍自拍| 久久午夜色播影院免费高清| 欧美一区二区精品| 伊人成人开心激情综合网| 欧美性jizz18性欧美| 欧美极品在线播放| 久久亚洲影音av资源网| 欧美在线视频一区二区三区| 亚洲一区国产| 一本到高清视频免费精品| 亚洲黄色在线视频| 欧美激情一区在线| 欧美激情一区二区在线| 欧美黑人国产人伦爽爽爽| 蜜桃av综合| 免费在线成人| 免费短视频成人日韩| 免费观看日韩| 欧美高清成人| 亚洲国产另类久久精品| 欧美成人第一页| 欧美高清影院| 亚洲精品激情| a4yy欧美一区二区三区| 亚洲视频在线观看三级| 久久久久综合网| 另类酷文…触手系列精品集v1小说| 久久精品免费电影| 久久久无码精品亚洲日韩按摩| 久久久国产精品一区二区中文| 久久婷婷一区| 欧美精品免费在线| 国产精品magnet| 国产亚洲精品bt天堂精选|