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

C++分析研究  
C++
日歷
<2014年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
統計
  • 隨筆 - 92
  • 文章 - 4
  • 評論 - 4
  • 引用 - 0

導航

常用鏈接

留言簿

隨筆檔案

文章檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

 

  構造函數中拋出的異常

  1、標準C++中定義構造函數是一個對象構建自己,分配所需資源的地方,一旦構造函數執行完畢,則表明這個對象已經誕生了,有自己的行為和內部的運行狀態,之后還有對象的消亡過程(析構函數的執行)。可誰能保證對象的構造過程一定能成功呢?說不定系統當前的某個資源不夠,導致對象不能完全構建好自己(人都有畸形兒,更何況別的呢?朋友們!是吧!),因此通過什么方法來表明對象的構造失敗了呢?C++程序員朋友們知道,C++中的構造函數是沒有返回值的,所以不少關于C++編程方面的書上得出結論:"因為構造函數沒有返回值,所以通知對象的構造失敗的唯一方法那就是在構造函數中拋出異常".主人公阿愚非常不同意這種說法,誰說的,便不信邪!雖然C++標準規定構造函數是沒有返回值,可我們知道每個函數實際上都會有一個返回值的,這個值被保存在eax寄存器中,因此實際上是有辦法通過編程來實現構造函數返回一個值給上層的對象創建者。當然即便是構造函數真的不能有返回值,我們也可以通過一個指針類型或引用類型的出參來獲知對象的構造過程的狀態。示例如下:

  class MyTest_Base

  {

  public:

  MyTest_Base (int& status)

  {

  //do other job

  // 由于資源不夠,對象構建失敗

  // 把status置0,通知對象的構建者

  status = 0;

  }

  protected:

  };

  void main()

  {

  int status;

  MyTest_Base obj1(status);

  // 檢查對象的構建是否成功

  if(status ==0) cout 《 "對象構建失敗" 《 endl;

  }

  程序運行的結果是:

  對象構建失敗

  是啊!上面我們不也得到了對象構造的成功與否的信息了嗎?可大家有沒有覺得這當中有點問題?主人公阿愚建議大家在此停留片刻,仔細想想它會有什么問題?OK!也許大家都知道了問題的所在,來驗證一下吧!

  class MyTest_Base

  {

  public:

  MyTest_Base (int& status)

  {

  //do other job

  // 由于資源不夠,對象構建失敗

  // 把status置0,通知對象的構建者

  status = 0;

  }

  virtual ~ MyTest_Base ()

  {

  cout 《 "銷毀一個MyTest_Base類型的對象" 《 endl;

  }

  protected:

  };

  void main()

  {

  int status;

  MyTest_Base obj1(status);

  // 檢查對象的構建是否成功

  if(status ==0) cout 《 "對象構建失敗" 《 endl;

  }

  程序運行的結果是:

  對象構建失敗

  銷毀一個MyTest_Base類型的對象

  沒錯,對象的析構函數被運行了,這與C++標準中所規定的面向對象的一些特性是有沖突的。一個對象都沒有完成自己的構造,又何來析構!好比一個夭折的畸形兒還沒有出生,又何來死之言。因此這種方法是行不通的。那怎么辦?那就是上面那個結論中的后一句話是對的,通知對象的構造失敗的唯一方法那就是在構造函數中拋出異常,但原因卻不是由于構造函數沒有返回值而造成的。恰恰相反,C++標準中規定構造函數沒有返回值正是由于擔心很容易與面向對象的一些特性相沖突,因此干脆來個規定,構造函數不能有返回值(主人公阿愚的個人理解,有不同意見的朋友歡迎討論)。

  2、構造函數中拋出異常將導致對象的析構函數不被執行。哈哈^-^,阿愚很開心,瞧瞧!如果沒有C++的異常處理機制鼎立支持,C++中的面向對象特性都無法真正實現起來,C++標準總不能規定所有的對象都必須成功構造吧!這也太理想化了,也許只有等到共產主義社會實現的那一天(CPU可以隨便拿,內存可以隨便拿,所有的資源都是你的!)才說不定有可能·····,所以說C++的異常處理和面向對象確實是誰也離不開誰。當然示例還是要看一下,如下:

  class MyTest_Base

  {

  public:

  MyTest_Base (string name = "") : m_name(name)

  {

  throw std::exception("在構造函數中拋出一個異常,測試!");

  cout 《 "構造一個MyTest_Base類型的對象,對象名為:"《m_name 《 endl;

  }

  virtual ~ MyTest_Base ()

  {

  cout 《 "銷毀一個MyTest_Base類型的對象,對象名為:"《m_name 《 endl;

  }

  void Func() throw()

  {

  throw std::exception("故意拋出一個異常,測試!");

  }

  void Other() {}

  protected:

  string m_name;

  };

  void main()

  {

  try

  {

  // 對象構造時將會拋出異常

  MyTest_Base obj1("obj1");

  obj1.Func();

  obj1.Other();

  }

  catch(std::exception e)

  {

  cout 《 e.what() 《 endl;

  }

  catch(…)

  {

  cout 《 "unknow exception"《 endl;

  }

  }

  程序的運行結果將會驗證:"構造函數中拋出異常將導致對象的析構函數不被執行"

  3、是不是到此,關于構造函數中拋出異常的處理的有關討論就能結束了呢?非也!非也!主人公阿愚還有進一步的故事需要講述!來看一個更復雜一點的例子吧!如下:

  class MyTest_Base

  {

  public:

  MyTest_Base (string name = "") : m_name(name)

  {

  cout 《 "構造一個MyTest_Base類型的對象,對象名為:"《m_name 《 endl;

  }

  virtual ~ MyTest_Base ()

  {

  cout 《 "銷毀一個MyTest_Base類型的對象,對象名為:"《m_name 《 endl;

  }

  void Func() throw()

  {

  throw std::exception("故意拋出一個異常,測試!");

  }

  void Other() {}

  protected:

  string m_name;

  };

  class MyTest_Parts

  {

  public:

  MyTest_Parts ()

  {

  cout 《 "構造一個MyTest_Parts類型的對象" 《 endl;

  }

  virtual ~ MyTest_Parts ()

  {

  cout 《 "銷毀一個MyTest_Parts類型的對象"《 endl;

  }

  };

  class MyTest_Derive : public MyTest_Base

  {

  public:

  MyTest_Derive (string name = "") : m_component(), MyTest_Base(name)

  {

  throw std::exception("在MyTest_Derive對象的構造函數中拋出了一個異常!");

  cout 《 "構造一個MyTest_Derive類型的對象,對象名為:"《m_name 《 endl;

  }

  virtual ~ MyTest_Derive ()

  {

  cout 《 "銷毀一個MyTest_Derive類型的對象,對象名為:"《m_name 《 endl;

  }

  protected:

  MyTest_Parts m_component;

  };

  void main()

  {

  try

  {

  // 對象構造時將會拋出異常

  MyTest_Derive obj1("obj1");

  obj1.Func();

  obj1.Other();

  }

  catch(std::exception e)

  {

  cout 《 e.what() 《 endl;

  }

  catch(…)

  {

  cout 《 "unknow exception"《 endl;

  }

  }

  程序運行的結果是:

  構造一個MyTest_Base類型的對象,對象名為:obj1

  構造一個MyTest_Parts類型的對象

  銷毀一個MyTest_Parts類型的對象

  銷毀一個MyTest_Base類型的對象,對象名為:obj1

  在MyTest_Derive對象的構造函數中拋出了一個異常!

  上面這個例子中,MyTest_Derive從MyTest_Base繼承,同時MyTest_Derive還有一個MyTest_Parts類型的成員變量。現在MyTest_Derive構造的時候,是在父類MyTest_Base已構造完畢和MyTest_Parts類型的成員變量m_component也已構造完畢之后,再拋出了一個異常,這種情況稱為對象的部分構造。是的,這種情況很常見,對象總是由不斷的繼承或不斷的聚合而來,對象的構造過程實際上是這些所有的子對象按規定順序的構造過程,其中這些過程中的任何一個子對象在構造時發生異常,對象都不能說自己完成了全部的構造過程,因此這里就有一個棘手的問題,當發生對象的部分構造時,對象將析構嗎?如果時,又將如何析構呢?托福答案

  從運行結果可以得出如下結論:

  (1) 對象的部分構造是很常見的,異常的發生點也完全是隨機的,程序員要謹慎處理這種情況;

  (2) 當對象發生部分構造時,已經構造完畢的子對象將會逆序地被析構(即異常發生點前面的對象);而還沒有開始構建的子對象將不會被構造了(即異常發生點后面的對象),當然它也就沒有析構過程了;還有正在構建的子對象和對象自己本身將停止繼續構建(即出現異常的對象),并且它的析構是不會被執行的。sat答案

  構造函數中拋出異常時概括性總結

  (1) C++中通知對象構造失敗的唯一方法那就是在構造函數中拋出異常;

  (2) 構造函數中拋出異常將導致對象的析構函數不被執行;

  (3) 當對象發生部分構造時,已經構造完畢的子對象將會逆序地被析構;

  (4) 其是還是那句話, "C++的異常處理不會破壞任何一條面向對象的特性!",因此主人公阿愚再次建議朋友們,牢牢記住這一條!

posted on 2014-01-10 21:30 HAOSOLA 閱讀(662) 評論(0)  編輯 收藏 引用
 
Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
PK10開獎 PK10開獎
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            免费在线观看日韩欧美| 亚洲激情视频| 香蕉成人啪国产精品视频综合网| 久久黄色网页| 欧美日韩一级黄| 亚洲精品一区在线观看香蕉| 亚洲国产欧美一区二区三区同亚洲| 亚洲一区二区3| 国产欧美日韩视频| 久久午夜影视| 欧美激情一区二区三区| 亚洲一区二区精品在线观看| 亚洲欧美精品| 影音先锋中文字幕一区二区| 亚洲级视频在线观看免费1级| 欧美区一区二| 欧美资源在线| 欧美激情第三页| 欧美一区二区日韩一区二区| 久久久久久9| 99精品视频免费观看| 亚洲在线播放电影| 亚洲国产成人91精品| 一二三四社区欧美黄| 国内欧美视频一区二区| 亚洲人成人一区二区三区| 国产精品一区二区久久久| 欧美电影专区| 国产农村妇女精品一二区| 欧美成人在线免费视频| 国产精品久久久久久久久久久久久久 | 亚洲免费观看在线观看| 亚洲视频二区| 亚洲人成毛片在线播放| 亚洲制服丝袜在线| 亚洲精品在线电影| 久久精品国产第一区二区三区最新章节| 亚洲人成欧美中文字幕| 欧美一区二区在线视频| 在线中文字幕一区| 麻豆国产va免费精品高清在线| 午夜精品久久久久久久久| 卡一卡二国产精品| 欧美一区二区三区视频免费| 欧美精品国产一区| 美女脱光内衣内裤视频久久网站| 国产精品久久久久77777| 最新日韩精品| 亚洲高清在线| 久久久欧美一区二区| 欧美在线欧美在线| 国产精品r级在线| 91久久精品国产91性色tv| 在线播放亚洲一区| 久久精品国产91精品亚洲| 香港成人在线视频| 国产精品午夜春色av| 一区二区三区久久网| 一区二区三区欧美亚洲| 欧美激情亚洲| 亚洲国产婷婷综合在线精品 | 久久精品国产一区二区三区免费看| 一本一本大道香蕉久在线精品| 欧美日韩国产精品专区| 欧美一区精品| 亚洲一区二区三区国产| 欧美国产视频日韩| 久久精品视频在线播放| 一区二区动漫| 亚洲人成毛片在线播放| 国内精品久久久久影院 日本资源| 欧美一区二区三区免费大片| 亚洲午夜高清视频| 亚洲成色精品| 日韩一级不卡| 亚洲欧美国产毛片在线| 欧美日韩久久精品| 久久久久亚洲综合| 亚洲人成在线播放网站岛国| 欧美一二三视频| 亚洲欧美日韩天堂一区二区| 亚洲美女色禁图| 亚洲日本中文字幕免费在线不卡| 久久久五月婷婷| 亚洲欧美日韩国产成人精品影院| 午夜精品久久久久久久99水蜜桃| 欧美国产日韩一区二区在线观看| 亚洲片在线观看| 亚洲午夜一区二区| 国产亚洲综合性久久久影院| 久久久999精品| 亚洲精品国产精品国自产在线 | 亚洲一区二区三区视频| 久久久久亚洲综合| 亚洲精品永久免费| 国产精品一二三四| 久久亚洲精品一区二区| 一本色道久久88综合日韩精品 | 亚洲人成久久| 国产九九视频一区二区三区| 免费成人性网站| 一个人看的www久久| 欧美成人69av| 亚洲欧美国产另类| 亚洲激情图片小说视频| 国产美女扒开尿口久久久| 欧美va亚洲va香蕉在线| 亚洲综合99| 亚洲人成77777在线观看网| 欧美呦呦网站| 在线视频欧美一区| 欧美一区2区视频在线观看| 91久久精品国产91性色tv| 久久久国产亚洲精品| 日韩系列欧美系列| 国产一区二区日韩精品| 欧美色道久久88综合亚洲精品| 久久精品国产一区二区三区免费看 | 亚洲黄色免费| 国产一区二区中文字幕免费看| 欧美精品免费播放| 久久久久综合一区二区三区| 中文精品在线| 亚洲日韩中文字幕在线播放| 欧美成人免费在线观看| 欧美一级大片在线观看| 亚洲一区二区欧美| 日韩一级片网址| 91久久视频| 亚洲国内欧美| 亚洲国产成人精品久久| 狠狠久久婷婷| 国产综合一区二区| 国产日韩视频| 国产农村妇女毛片精品久久麻豆 | 香蕉av福利精品导航| 在线亚洲电影| 一区二区三区国产盗摄| 亚洲美女黄网| 日韩视频在线观看| 日韩亚洲精品电影| 亚洲美女毛片| 一本到12不卡视频在线dvd| 亚洲精品在线三区| 亚洲人永久免费| 亚洲免费av电影| 一区二区三区日韩欧美精品| 一区二区三区三区在线| 亚洲视屏一区| 亚洲免费在线精品一区| 欧美一区2区三区4区公司二百| 久久成人免费电影| 久久人人超碰| 欧美国产先锋| 欧美午夜免费影院| 国产热re99久久6国产精品| 国产亚洲成av人在线观看导航| 国产一区二区三区高清| 一区二区三区我不卡| 91久久久亚洲精品| 一本一本久久a久久精品综合麻豆| 亚洲婷婷综合色高清在线| 亚洲欧美在线网| 久久久国产成人精品| 欧美黑人国产人伦爽爽爽| 亚洲精品亚洲人成人网| 亚洲女同性videos| 久久全国免费视频| 欧美另类变人与禽xxxxx| 国产精品欧美日韩久久| 国模吧视频一区| 日韩天堂av| 欧美在线视频在线播放完整版免费观看| 久久精品午夜| 亚洲第一在线综合网站| 亚洲网站在线| 久久性天堂网| 国产精品家教| 亚洲激情电影中文字幕| 亚洲欧美视频一区| 欧美成人国产一区二区| 一区二区三区产品免费精品久久75| 先锋影音国产精品| 欧美激情免费在线| 含羞草久久爱69一区| 一区二区三区高清视频在线观看| 久久精品国产一区二区三| 亚洲片在线资源| 久久久蜜桃一区二区人| 亚洲欧美电影院| 久久久午夜精品| 99re热这里只有精品免费视频| 欧美伊人久久久久久久久影院| 欧美国产成人在线| 国产亚洲激情| 亚洲一区精彩视频| 亚洲黄色有码视频| 久久精品一区二区三区中文字幕| 国产精品v欧美精品v日本精品动漫 | 亚洲一区二区成人在线观看|