• <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>
            C++分析研究  
            C++
            日歷
            <2014年1月>
            2930311234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678
            統(tǒng)計(jì)
            • 隨筆 - 92
            • 文章 - 4
            • 評(píng)論 - 4
            • 引用 - 0

            導(dǎo)航

            常用鏈接

            留言簿

            隨筆檔案

            文章檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

             

              構(gòu)造函數(shù)中拋出的異常

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

              class MyTest_Base

              {

              public:

              MyTest_Base (int& status)

              {

              //do other job

              // 由于資源不夠,對(duì)象構(gòu)建失敗

              // 把status置0,通知對(duì)象的構(gòu)建者

              status = 0;

              }

              protected:

              };

              void main()

              {

              int status;

              MyTest_Base obj1(status);

              // 檢查對(duì)象的構(gòu)建是否成功

              if(status ==0) cout 《 "對(duì)象構(gòu)建失敗" 《 endl;

              }

              程序運(yùn)行的結(jié)果是:

              對(duì)象構(gòu)建失敗

              是啊!上面我們不也得到了對(duì)象構(gòu)造的成功與否的信息了嗎?可大家有沒有覺得這當(dāng)中有點(diǎn)問(wèn)題?主人公阿愚建議大家在此停留片刻,仔細(xì)想想它會(huì)有什么問(wèn)題?OK!也許大家都知道了問(wèn)題的所在,來(lái)驗(yàn)證一下吧!

              class MyTest_Base

              {

              public:

              MyTest_Base (int& status)

              {

              //do other job

              // 由于資源不夠,對(duì)象構(gòu)建失敗

              // 把status置0,通知對(duì)象的構(gòu)建者

              status = 0;

              }

              virtual ~ MyTest_Base ()

              {

              cout 《 "銷毀一個(gè)MyTest_Base類型的對(duì)象" 《 endl;

              }

              protected:

              };

              void main()

              {

              int status;

              MyTest_Base obj1(status);

              // 檢查對(duì)象的構(gòu)建是否成功

              if(status ==0) cout 《 "對(duì)象構(gòu)建失敗" 《 endl;

              }

              程序運(yùn)行的結(jié)果是:

              對(duì)象構(gòu)建失敗

              銷毀一個(gè)MyTest_Base類型的對(duì)象

              沒錯(cuò),對(duì)象的析構(gòu)函數(shù)被運(yùn)行了,這與C++標(biāo)準(zhǔn)中所規(guī)定的面向?qū)ο蟮囊恍┨匦允怯袥_突的。一個(gè)對(duì)象都沒有完成自己的構(gòu)造,又何來(lái)析構(gòu)!好比一個(gè)夭折的畸形兒還沒有出生,又何來(lái)死之言。因此這種方法是行不通的。那怎么辦?那就是上面那個(gè)結(jié)論中的后一句話是對(duì)的,通知對(duì)象的構(gòu)造失敗的唯一方法那就是在構(gòu)造函數(shù)中拋出異常,但原因卻不是由于構(gòu)造函數(shù)沒有返回值而造成的。恰恰相反,C++標(biāo)準(zhǔn)中規(guī)定構(gòu)造函數(shù)沒有返回值正是由于擔(dān)心很容易與面向?qū)ο蟮囊恍┨匦韵鄾_突,因此干脆來(lái)個(gè)規(guī)定,構(gòu)造函數(shù)不能有返回值(主人公阿愚的個(gè)人理解,有不同意見的朋友歡迎討論)。

              2、構(gòu)造函數(shù)中拋出異常將導(dǎo)致對(duì)象的析構(gòu)函數(shù)不被執(zhí)行。哈哈^-^,阿愚很開心,瞧瞧!如果沒有C++的異常處理機(jī)制鼎立支持,C++中的面向?qū)ο筇匦远紵o(wú)法真正實(shí)現(xiàn)起來(lái),C++標(biāo)準(zhǔn)總不能規(guī)定所有的對(duì)象都必須成功構(gòu)造吧!這也太理想化了,也許只有等到共產(chǎn)主義社會(huì)實(shí)現(xiàn)的那一天(CPU可以隨便拿,內(nèi)存可以隨便拿,所有的資源都是你的!)才說(shuō)不定有可能·····,所以說(shuō)C++的異常處理和面向?qū)ο蟠_實(shí)是誰(shuí)也離不開誰(shuí)。當(dāng)然示例還是要看一下,如下:

              class MyTest_Base

              {

              public:

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

              {

              throw std::exception("在構(gòu)造函數(shù)中拋出一個(gè)異常,測(cè)試!");

              cout 《 "構(gòu)造一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              virtual ~ MyTest_Base ()

              {

              cout 《 "銷毀一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              void Func() throw()

              {

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

              }

              void Other() {}

              protected:

              string m_name;

              };

              void main()

              {

              try

              {

              // 對(duì)象構(gòu)造時(shí)將會(huì)拋出異常

              MyTest_Base obj1("obj1");

              obj1.Func();

              obj1.Other();

              }

              catch(std::exception e)

              {

              cout 《 e.what() 《 endl;

              }

              catch(…)

              {

              cout 《 "unknow exception"《 endl;

              }

              }

              程序的運(yùn)行結(jié)果將會(huì)驗(yàn)證:"構(gòu)造函數(shù)中拋出異常將導(dǎo)致對(duì)象的析構(gòu)函數(shù)不被執(zhí)行"

              3、是不是到此,關(guān)于構(gòu)造函數(shù)中拋出異常的處理的有關(guān)討論就能結(jié)束了呢?非也!非也!主人公阿愚還有進(jìn)一步的故事需要講述!來(lái)看一個(gè)更復(fù)雜一點(diǎn)的例子吧!如下:

              class MyTest_Base

              {

              public:

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

              {

              cout 《 "構(gòu)造一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              virtual ~ MyTest_Base ()

              {

              cout 《 "銷毀一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              void Func() throw()

              {

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

              }

              void Other() {}

              protected:

              string m_name;

              };

              class MyTest_Parts

              {

              public:

              MyTest_Parts ()

              {

              cout 《 "構(gòu)造一個(gè)MyTest_Parts類型的對(duì)象" 《 endl;

              }

              virtual ~ MyTest_Parts ()

              {

              cout 《 "銷毀一個(gè)MyTest_Parts類型的對(duì)象"《 endl;

              }

              };

              class MyTest_Derive : public MyTest_Base

              {

              public:

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

              {

              throw std::exception("在MyTest_Derive對(duì)象的構(gòu)造函數(shù)中拋出了一個(gè)異常!");

              cout 《 "構(gòu)造一個(gè)MyTest_Derive類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              virtual ~ MyTest_Derive ()

              {

              cout 《 "銷毀一個(gè)MyTest_Derive類型的對(duì)象,對(duì)象名為:"《m_name 《 endl;

              }

              protected:

              MyTest_Parts m_component;

              };

              void main()

              {

              try

              {

              // 對(duì)象構(gòu)造時(shí)將會(huì)拋出異常

              MyTest_Derive obj1("obj1");

              obj1.Func();

              obj1.Other();

              }

              catch(std::exception e)

              {

              cout 《 e.what() 《 endl;

              }

              catch(…)

              {

              cout 《 "unknow exception"《 endl;

              }

              }

              程序運(yùn)行的結(jié)果是:

              構(gòu)造一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:obj1

              構(gòu)造一個(gè)MyTest_Parts類型的對(duì)象

              銷毀一個(gè)MyTest_Parts類型的對(duì)象

              銷毀一個(gè)MyTest_Base類型的對(duì)象,對(duì)象名為:obj1

              在MyTest_Derive對(duì)象的構(gòu)造函數(shù)中拋出了一個(gè)異常!

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

              從運(yùn)行結(jié)果可以得出如下結(jié)論:

              (1) 對(duì)象的部分構(gòu)造是很常見的,異常的發(fā)生點(diǎn)也完全是隨機(jī)的,程序員要謹(jǐn)慎處理這種情況;

              (2) 當(dāng)對(duì)象發(fā)生部分構(gòu)造時(shí),已經(jīng)構(gòu)造完畢的子對(duì)象將會(huì)逆序地被析構(gòu)(即異常發(fā)生點(diǎn)前面的對(duì)象);而還沒有開始構(gòu)建的子對(duì)象將不會(huì)被構(gòu)造了(即異常發(fā)生點(diǎn)后面的對(duì)象),當(dāng)然它也就沒有析構(gòu)過(guò)程了;還有正在構(gòu)建的子對(duì)象和對(duì)象自己本身將停止繼續(xù)構(gòu)建(即出現(xiàn)異常的對(duì)象),并且它的析構(gòu)是不會(huì)被執(zhí)行的。sat答案

              構(gòu)造函數(shù)中拋出異常時(shí)概括性總結(jié)

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

              (2) 構(gòu)造函數(shù)中拋出異常將導(dǎo)致對(duì)象的析構(gòu)函數(shù)不被執(zhí)行;

              (3) 當(dāng)對(duì)象發(fā)生部分構(gòu)造時(shí),已經(jīng)構(gòu)造完畢的子對(duì)象將會(huì)逆序地被析構(gòu);

              (4) 其是還是那句話, "C++的異常處理不會(huì)破壞任何一條面向?qū)ο蟮奶匦裕?,因此主人公阿愚再次建議朋友們,牢牢記住這一條!

            posted on 2014-01-10 21:30 HAOSOLA 閱讀(651) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


             
            Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
            PK10開獎(jiǎng) PK10開獎(jiǎng)
            亚洲AV无码1区2区久久| 国产成人久久激情91| 一级做a爰片久久毛片毛片| 久久婷婷五月综合色奶水99啪| 综合网日日天干夜夜久久| 日韩人妻无码一区二区三区久久 | 成人久久精品一区二区三区| 91精品无码久久久久久五月天| 一本久道久久综合狠狠躁AV| 国产一级做a爰片久久毛片| 免费精品久久久久久中文字幕 | 爱做久久久久久| 思思久久精品在热线热| 国产精品久久久久9999| 国内精品伊人久久久久777| 天天爽天天爽天天片a久久网| 亚洲中文精品久久久久久不卡| 国产视频久久| 狠狠综合久久综合88亚洲| 久久国产乱子伦精品免费强| 亚洲国产精品无码成人片久久| 久久996热精品xxxx| 婷婷综合久久中文字幕蜜桃三电影 | 久久亚洲精品国产亚洲老地址| 女人香蕉久久**毛片精品| 精品多毛少妇人妻AV免费久久| 成人精品一区二区久久久| 97久久久精品综合88久久| 伊人久久大香线蕉综合影院首页| 人妻少妇精品久久| 国产精品成人久久久久久久| 久久国产精品一区二区| 国产精品久久久天天影视| 国产成人精品白浆久久69| 久久精品国产亚洲av日韩| 久久综合精品国产二区无码| 日韩乱码人妻无码中文字幕久久| 久久AV高潮AV无码AV| 一本色道久久综合狠狠躁| 狠狠色狠狠色综合久久| 精品久久人人爽天天玩人人妻|