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

幽幽
 
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指針,非要的話用智能指針……這樣固有的機制可以讓你連析構函數都不用寫。  回復  更多評論
  

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(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>
            久久国内精品视频| 日韩亚洲成人av在线| 午夜精品一区二区三区四区| 亚洲在线观看免费视频| 蜜臀av一级做a爰片久久| 国产精品白丝黑袜喷水久久久| 国产欧美一二三区| 亚洲一区二区高清| 久久精品视频亚洲| 亚洲国内在线| 国产欧美短视频| 亚洲美女av在线播放| 欧美福利视频一区| 欧美r片在线| 亚洲精品国产无天堂网2021| 中文精品视频| 91久久精品视频| 欧美激情视频给我| 一区二区三区四区国产| 一区二区不卡在线视频 午夜欧美不卡在 | 老牛国产精品一区的观看方式| 欧美电影在线观看| 久久综合影视| 日韩午夜免费| 99日韩精品| 亚洲欧洲av一区二区三区久久| 蘑菇福利视频一区播放| 夜夜嗨av一区二区三区| 国产精品99久久久久久白浆小说| 国产精品国产三级国产普通话99 | 亚洲一区bb| 亚洲综合色激情五月| 激情小说另类小说亚洲欧美| 久久综合网络一区二区| 欧美国内亚洲| 亚洲免费高清| 一区二区视频欧美| 另类激情亚洲| 午夜精品久久久久久久99水蜜桃 | 亚洲香蕉网站| 久久激情五月激情| 在线中文字幕一区| 久久深夜福利免费观看| 亚洲视频电影在线| 欧美成在线视频| 亚洲男人av电影| 在线观看日韩一区| 亚洲欧洲在线看| 午夜亚洲性色福利视频| 国产在线乱码一区二区三区| 一本久道久久综合狠狠爱| 国产精品久久91| 日韩一级在线| 亚洲国产精品成人| 亚洲影院免费观看| 欧美三级电影一区| 日韩午夜一区| 国产精品久久久久久久久免费桃花| 欧美高清在线观看| 国产精品久久二区| 亚洲综合色激情五月| 欧美在线亚洲综合一区| 免费在线日韩av| 欧美v国产在线一区二区三区| 99视频一区二区三区| 午夜久久tv| 欧美色精品天天在线观看视频| 久久久最新网址| 免费久久99精品国产| 久久综合给合| 一区二区三区欧美日韩| 亚洲第一页中文字幕| 精品999成人| 女同性一区二区三区人了人一| 欧美二区在线观看| 国产午夜亚洲精品羞羞网站 | 久久久久久999| 亚洲国产欧美另类丝袜| 国产美女精品免费电影| 久久综合一区二区三区| 亚洲黄色免费电影| 久久综合色婷婷| 亚洲综合视频网| 国产视频丨精品|在线观看| 欧美精品18videos性欧美| 亚洲人成人99网站| 亚洲欧美色婷婷| 91久久久久| 亚洲一二三区在线观看| 亚洲国产小视频| 欧美成人首页| 久久人人超碰| 久久九九有精品国产23| 亚洲欧美综合| 欧美自拍偷拍| 免费成人小视频| 亚洲第一级黄色片| 欧美激情久久久久久| 亚洲第一黄色网| 亚洲激情综合| 9久草视频在线视频精品| 99国内精品久久久久久久软件| 亚洲精品字幕| 亚洲欧美日韩视频一区| 欧美在线免费视屏| 久久天堂精品| 亚洲黄色视屏| 欧美丰满少妇xxxbbb| 亚洲欧美久久| 欧美日韩亚洲一区二区三区在线观看 | 亚洲第一精品在线| 午夜精品视频| 国产精品久久久久久av下载红粉 | 亚洲黄色在线| 亚洲精品国产精品国自产观看浪潮 | 一本一道久久综合狠狠老精东影业| 亚洲综合成人在线| 亚洲国产日本| 欧美三级视频在线观看| 在线亚洲一区二区| 亚洲一区二区三区四区五区午夜 | 亚洲日本va午夜在线影院| 你懂的成人av| 欧美日韩成人在线视频| 午夜在线精品| 亚洲曰本av电影| 国产亚洲一区在线| 麻豆免费精品视频| 欧美成人精品1314www| 亚洲精品三级| 亚洲精品三级| 国产精品国产三级国产aⅴ9色| 欧美va天堂在线| 91久久精品日日躁夜夜躁欧美| 免播放器亚洲| 欧美电影在线观看完整版| 亚洲精品一区二区三区av| 亚洲国产精品高清久久久| 欧美国产视频日韩| 亚洲无吗在线| 看片网站欧美日韩| 欧美一区二区观看视频| 欧美一级播放| 国产一区二区久久| 亚洲精品乱码久久久久久蜜桃91| 久久久欧美一区二区| 亚洲欧美日韩国产一区| 久久亚洲电影| 午夜久久久久久久久久一区二区| 午夜日韩在线| 亚洲精品裸体| 亚洲欧美日韩国产综合精品二区| 在线看无码的免费网站| 在线亚洲欧美专区二区| 黄色免费成人| 亚洲图片欧美一区| 亚洲精品久久久久| 亚洲欧美国产日韩中文字幕| 亚洲经典在线| 久久精品一区二区三区不卡| aa成人免费视频| 久久久久国产精品午夜一区| 欧美一区二区三区四区夜夜大片 | 国产目拍亚洲精品99久久精品| 亚洲黄色尤物视频| 一区二区三区日韩欧美| 国产精品一区久久久| 噜噜噜躁狠狠躁狠狠精品视频| 久久精品国产99| 国产精品私房写真福利视频| 一区二区欧美日韩| 亚洲欧美国产精品va在线观看| 久久久亚洲一区| 欧美一区二区三区视频在线| 国产精品一区二区三区久久久| 99伊人成综合| 亚洲欧美一区二区在线观看| 国产伦精品一区二区三区照片91| 国产自产2019最新不卡| 羞羞答答国产精品www一本| 欧美资源在线观看| 一区二区av在线| 激情视频一区二区| 欧美在线视频二区| 国内久久视频| 国产精品福利网站| 欧美一区二区三区四区在线 | 欧美va天堂| 免费在线亚洲欧美| 99精品久久久| 亚洲在线免费| 亚洲精品视频免费在线观看| 亚洲精品日韩久久| 这里只有精品视频| 18成人免费观看视频| 亚洲欧洲一区二区在线播放| 亚洲激情在线| 国产视频自拍一区| 久久综合色影院| 国产精品国产精品国产专区不蜜|