版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第七章異常及其處理(exception and its handling7.1程序運(yùn)行錯(cuò)誤及其處理程序在運(yùn)行中可能出錯(cuò),例如在除法運(yùn)算中用0作除數(shù)、求負(fù)數(shù)的開(kāi)方根、在計(jì)算機(jī)監(jiān)控系統(tǒng)中所采集的數(shù)據(jù)越限,等等。當(dāng)程序出錯(cuò)時(shí),一般要求用戶進(jìn)行 處理,如重新輸入數(shù)值或給出新的控制量等。必要時(shí)則中斷程序。程序首先應(yīng)檢 測(cè)到出錯(cuò),然后才能提示用戶進(jìn)行處理或由程序自動(dòng)進(jìn)行處理。傳統(tǒng)的錯(cuò)誤處理方式唯有依靠函數(shù)返回提示錯(cuò)誤用的局部標(biāo)志數(shù)據(jù)或者全局 標(biāo)志數(shù)據(jù)來(lái)提示出錯(cuò)(全局?jǐn)?shù)據(jù)的安全性差,極易受到破壞)。這類(lèi)做法的困難是 程序只能在函數(shù)返回主程序后才能檢查標(biāo)志數(shù)據(jù)。錯(cuò)誤處理的一種新的方式是使用“異?!?excep
2、tion)。異常處理是由程序設(shè)計(jì) 語(yǔ)言提供的運(yùn)行時(shí)刻錯(cuò)誤處理的一種方式。一旦程序出現(xiàn)錯(cuò)誤,隨即引發(fā)和拋出“異?!保绦蚰茉谝惶幓蚨嗵幒线m的地方自動(dòng)地捕獲異常并進(jìn)行必要的處理。例1求負(fù)數(shù)的開(kāi)方根時(shí)傳統(tǒng)的錯(cuò)誤處理方式:/ sqrt_negative_1.cpp/ error occurs when the square root of a negative number is calculated/ system subroutine used#include <iostream.h>#include <math.h> / ptototype: double sqrt( d
3、ouble );#include <stdlib.h> / ptototype: void exit(int);double sqroot(double number)if ( number < 0 )cout << "Error! negative input number : " << number << 'n'cout << "Program terminated!" << 'n'exit( -1 );return sqrt( number
4、 ); /system subroutinevoid main()cout<<"Sqrt of 1.5129 is "<<sqroot(1.5129)<<endl;cout<<"Sqrt of -4 is "<<sqroot(-4)<<endl;cout<<"Sqrt of 16 is "<<sqroot(16)<<endl;/* Results:Sqrt of 1.5129 is 1.23Error! negative inp
5、ut number : -4Program terminated!*/以上程序中,當(dāng)準(zhǔn)備求取負(fù)數(shù)的平方根時(shí),就出錯(cuò),程序非正常結(jié)束。為使程序非正常結(jié)束,須要調(diào)用系統(tǒng)子程序exit( ),其函數(shù)原型在頭文件stdlib.h 內(nèi)。其中主函數(shù)中第二句運(yùn)行過(guò)程中,因調(diào)用函數(shù)sqroot(-4)B導(dǎo)致程序意外中斷。但在sqroot(-4)前的字符串"Sqrt of-4 is ”卻沒(méi)有顯示。這類(lèi)現(xiàn)象將在以后眾多程 序中出現(xiàn)。它是由于輸出語(yǔ)句的整體性所決定的。 請(qǐng)見(jiàn)第八章§ 8.1.2.2“非緩沖輸出流”中的詳細(xì)解釋。例 2第五章§ 5.3.1.3“除法運(yùn)算符重載”中的例 1該
6、程序中的子程序double division:operator / ( double denominator ) if ( denominator = 0 ) cout<<"attempted to divide by zero"<<endl; return -999999;return (numerator/denominator); 將-999999 的返回值作為錯(cuò)誤標(biāo)志。 void main() double numerator, denominator;double result;division num(numerator);result
7、= num/denominator;/i.e. result=num. operator / ( denominator )if ( result = -999999 ) cout << "The quotient is meaningless!" << endl;cout << "Try again!" << endl;主函數(shù) main( )在子函數(shù) double division:operator / ( double denominator )返回主函數(shù)后立即檢查返回值,如發(fā)現(xiàn)出錯(cuò),就加以顯示。如果程
8、序中出錯(cuò)地方較多,這類(lèi)處理方法就有其局限性:當(dāng)調(diào)用函數(shù)的級(jí)聯(lián)數(shù)量較多(即一個(gè)函數(shù)調(diào)用下一個(gè)函數(shù),而下一個(gè)又調(diào)用再下一個(gè)的級(jí)聯(lián)方式)而又需要在其它地方(例如上級(jí)的上級(jí)的上級(jí))統(tǒng)一進(jìn)行處理時(shí),逐級(jí)傳遞錯(cuò)誤碼太繁瑣。因此須要借助于異常處理。請(qǐng)參閱后面本章§ 7.2.1 “拋出異?!敝械睦?3中的程序exception_5.cpp。 例 3 依靠異常來(lái)處理求負(fù)數(shù)開(kāi)方根的例子 (當(dāng)然此例中并不一定需要異常處理) :/ exception_sqrt_1.cpp/ exception occurs when the square root of a negative number is calcu
9、lated#include <iostream.h>#include <math.h> / ptototype: double sqrt( double );/#include <stdlib.h> /不再需要 exit( )double sqroot(double number)if ( number < 0 ) throw number; /exception objectreturn sqrt( number ); /system subroutine void main() try cout<<"Sqrt of 1.512
10、9 is "<<sqroot(1.5129)<<endl;cout<<"Sqrt of -4 is "<<sqroot(-4)<<endl;cout<<"Sqrt of 16 is "<<sqroot(16)<<endl;catch ( double ) / exception handlercout << "Error! negative input number" << 'n'cout
11、<< "Program terminated!" << 'n'/exit( -1 );/因已到程序結(jié)尾,故不再需要此函數(shù)/* Results:Sqrt of 1.5129 is 1.23Error! negative input number Program terminated!*/一種較好的編程方式是首先編寫(xiě)正常運(yùn)行的代碼,然后再添加用于處理 各類(lèi)異常情況的語(yǔ)句。7.2 異常及其處理7.2.1 拋出異常從上節(jié)例2中可以看出,當(dāng)監(jiān)測(cè)到程序出錯(cuò)時(shí),就拋出異常。其格式為: try監(jiān)測(cè)到(或在被調(diào)用的程序中監(jiān)測(cè)到)程序出錯(cuò)時(shí), throw
12、異常對(duì)象;其中被拋出的異常對(duì)象可以是預(yù)定義數(shù)據(jù)類(lèi)型(例如int、double char*等)的變量及其指針和引用,但更經(jīng)常使用的是各種異常類(lèi)的對(duì)象及其指針和引用。使用這些異常類(lèi)對(duì)象的優(yōu)點(diǎn)是能夠提供更多關(guān)于程序錯(cuò)誤的信息,包括處理各類(lèi) 錯(cuò)誤的方法。這些異常類(lèi)可以是系統(tǒng)所提供的.更多情況下可以是用戶自己定義應(yīng)該注意:此處要求一定在try程序塊中或它所調(diào)用的函數(shù)中拋出異常。以下是不在try程序塊中而在try程序塊所調(diào)用的函數(shù)中拋出異常的例子:例1在try程序塊所調(diào)用的函數(shù)quotient()中拋出異常的例子/ exception_1.cpp/ A simple exception handling
13、example./ Checking for a divide-by-zero exception/ and throwing an intetger as an exception#include <iostream.h>/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered. double quotient( double numerator, double divisor )if ( divisor
14、 = 0 ) throw divisor;被拋出的異常對(duì)象是預(yù)定義類(lèi)型即double型數(shù)據(jù)return numerator / divisor;/ Driver programvoid main()/ the try block wraps the code that may throw an/ exception and the code that should not execute/ if an exception occurstry cout << "The quotient of 18/9 is " << quotient ( 18, 9
15、) << endl;cout << "The quotient of 18/0 is " << quotient ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( double dd ) / exception handlercout << "Exception : divisor " << d
16、d << " used!" << endl;/* Results:The quotient of 18/9 is 2Exception : divisor 0 used!*/從以上例子中可以看出,當(dāng)程序不出錯(cuò)時(shí),程序按照順序控制結(jié)構(gòu)逐條語(yǔ)句 地向下執(zhí)行,并返回除法運(yùn)算結(jié)果。而當(dāng)程序出錯(cuò)時(shí)(即當(dāng)除數(shù)為零時(shí)) ,程序就 在拋出異常處中斷,不再執(zhí)行以后的語(yǔ)句(不執(zhí)行第三句),并跳轉(zhuǎn)至catch程序 塊再繼續(xù)往下執(zhí)行程序。例2使用系統(tǒng)的異常類(lèi)class exception為止匕,須包含頭文件exception,/ exception_3.cpp/ same
17、as exception_1.cpp, only differing in/ throwing an object of a class instead of a double value#include <iostream.h>#includeexception,/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered.double quotient( double numerator, double d
18、ivisor )if ( divisor = 0 ) throw exception();被拋出的異常對(duì)象是異常類(lèi)即 class exception勺對(duì)象,/class exception is declared in the include file <exception> return numerator / divisor;/ Driver programvoid main()try cout << "The quotient of 18/9 is " << quotient (18, 9 ) << endl;cout
19、<< "The quotient of 18/0 is " << quotient ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handler cout << ex.what( ) << 'n'/* Results:The quotient of 18
20、/9 is 2Unknown exception */以上程序中class exceptions系統(tǒng)所提供的異常類(lèi),在拋出異常時(shí)建立該異常 類(lèi)exception的對(duì)象。為使用class exception在程序中應(yīng)包含頭文件exception,, 在§7.3中將會(huì)詳細(xì)介紹它。catch程序塊中內(nèi)容將在下一小節(jié)§7.2.2中介紹。以上程序中,當(dāng)出現(xiàn)異常時(shí),拋出異常,程序流即自動(dòng)退出 try程序塊,進(jìn)入 catch程序塊,進(jìn)行處理后即進(jìn)入 catch程序塊以后的語(yǔ)句,不再繼續(xù)執(zhí)行 try程 序塊中拋出異常語(yǔ)句后的其他語(yǔ)句(上例中不再執(zhí)行第三條語(yǔ)句“ quotient (4.5,
21、 9 )”)。以上程序中無(wú)法顯示異常內(nèi)容,但只需將以上程序略加修改,即可顯示異常 內(nèi)容。如exception_4.cpp(未顯示整個(gè)程序)中,只需將 double quotient( int numerator, int divisor )函數(shù)的第 旬“ if ( divisor = 0 )throw exceptio,); ”改為:“if ( divisor = 0 ) throw exceptio, "Divide-by-zero exception");使用系統(tǒng)的異常類(lèi)的對(duì)象并初始化”即可!也就是在建立 class exception的對(duì)象時(shí),使用字符串"d
22、ivide-by-zero exception,將該異常對(duì)象的字符串?dāng)?shù)據(jù)初始化,輸入用于顯示異常性質(zhì)的字符串。在調(diào)用異常對(duì)象中的 what()函數(shù)時(shí)就能顯示該字符串。這就獲得如下更明確的運(yùn)行結(jié)果:/* Results:The quotient of 18/9 is 2Divide-by-zero exception*/以前提到過(guò),當(dāng)函數(shù)級(jí)聯(lián)調(diào)用時(shí),使用顯示出錯(cuò)的函數(shù)返回值,要逐級(jí)向上 遞送,很不方便。而使用異常處理就方便了。例3函數(shù)級(jí)聯(lián)調(diào)用時(shí)的異常處理/ exception_5.cpp/ cascaded invocation of sub-routines#include <iostr
23、eam.h>#include <exception>/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered. double quotient( double numerator, double divisor )if ( divisor = 0 ) throw exception( "Divide-by-zero exception");/使用系統(tǒng)的異常類(lèi)return numer
24、ator / divisor;double h( double numerator, double divisor )double result = quotient( numerator, divisor );cout << "function h( ) in return path!" << endl;return result;double g( double numerator, double divisor )double result = h( numerator, divisor );cout << "functi
25、on g( ) in return path!" << endl;return result;double f( double numerator, double divisor )double result = g( numerator, divisor );cout << "function f( ) in return path!" << endl;return result;/ Driver programvoid main()try cout << "The quotient of 18/9 is
26、 " << f ( 18, 9 ) << endl;cout << "The quotient of 18/0 is " << f ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << f ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handlercout << ex.what( ) << 'n&
27、#39;/* Results:function h( ) in return path!function g( ) in return path!function f( ) in return path!The quotient of 18/9 is 2Divide-by-zero exception*/以上程序中正常調(diào)用函數(shù)的路徑是: main( ) -> f( ) -> g( ) -> h( ) ->quotient( ) , 在函數(shù)返回時(shí)則采取相反路徑,即 quotient( ) -> h( ) -> g( ) -> f( ) -> mai
28、n( ) 。但在出現(xiàn)異常時(shí),也即調(diào)用主函數(shù)中以下語(yǔ)句cout << "The quotient of 18/0 is " << f ( 18, 0 ) << endl;時(shí),就不再按步就班,而是直接從 quotient (泅回至main()中的catch程序塊。其流程如下圖所示:其中正常運(yùn)行流程引發(fā)異常流程表示函數(shù)調(diào)用路徑*表示正常返回路徑- 表示出現(xiàn)異常時(shí)的返回路徑7.2.2 捕獲異常捕獲異常以便進(jìn)行處理時(shí),通常使用 catch程序塊,其格式為:catch (數(shù)據(jù)或類(lèi)的對(duì)象)程序塊可在該程序塊中顯示相關(guān)信息和進(jìn)行必要處理。例1使用異常檢查
29、整型數(shù)組下標(biāo)越限/ exception_7.cpp/使用異常后查整型數(shù)組下標(biāo)越限#include <iostream.h>int arr = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;int LEN; / number of elementsdouble f(int i)if ( (i>=LEN) | (i<0)throw i;return arri;void main()/ Number of elements is determined firstLEN = sizeof(arr)/sizeof(arr0);try cout<<&quo
30、t;arr1="<<f(1)<<endl;cout<<"arr4="<<f(4)<<endl;cout<<"arr-2="<<f(-2)<<endl;catch (int x) cout << "Exception:subscript "<< x<<" beyond limits (number of elements = "<<LEN<<"
31、)" << endl;/* Results:arr1=2arr4=5Exception:subscript -2 beyond limits (number of elements = 10)*/以上程序中,主程序首先自動(dòng)地確定數(shù)組單元數(shù)。無(wú)論該數(shù)組類(lèi)型如何,都可正確地求得。當(dāng)下標(biāo)越限時(shí),就拋出異常。稍后在catch 程序塊中捕獲異常,并顯示該下標(biāo)的數(shù)值。以上是捕獲一個(gè)異常的例子,以下是捕獲兩個(gè)異常并作不同顯示的例子: 例 2 輸入兩個(gè)數(shù)值,兩者相除,求其商。如分母為零,拋出第一類(lèi)異常。如錯(cuò)誤地輸入錯(cuò)誤類(lèi)型的變量例如字符變量,則拋出第二類(lèi)異常。這兩類(lèi)異常由一個(gè)catch
32、程序塊捕獲,而能作不同顯示處理。/ exception_6.cpp/ different exceptions caught by one block#include <iostream.h>#include <exception>double quotient( double numerator, double divisor )if ( divisor = 0 )throw exception( "Divide-by-zero exception" );/使用系統(tǒng)的異常類(lèi)并初始化其對(duì)象return numerator / divisor;void
33、 main()double numerator, divisor;cout << "Enter two values: "cin >> numerator >> divisor;try if (!cin)throw exception( "Wrong input type exception" );cout << "The quotient of "<<numerator<<'/'<<divisor<<" is &
34、quot;<< quotient ( numerator, divisor ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handler cout << ex.what( ) << 'n'/* Three kinds of results:(1)Enter two values: 18 9The qu
35、otient of 18/9 is 2The quotient of 4.5/9 is 0.5(2)Enter two values: 18 0Divide-by-zero exception(3)Enter two values: 18 pWrong input type exception*/上例中如分母為零,拋出一個(gè)異常類(lèi)對(duì)象。如錯(cuò)誤地輸入字符變量,則拋出另一 個(gè)異常類(lèi)對(duì)象。這兩類(lèi)異常類(lèi)對(duì)象的差別在于其初始化字符串內(nèi)容不同。它們都能 由同一個(gè)catch程序塊捕獲,進(jìn)行處理,顯示不同內(nèi)容:對(duì)第一個(gè)異常類(lèi)對(duì)象顯示“ Divideby-zero exception ; 對(duì)另 個(gè)異常 類(lèi)對(duì)象 貝
36、 顯示 “Wronginput type exception :'程序中(!cin)是“operator!("個(gè)重載運(yùn)算符函數(shù))和“cin”(一個(gè)輸入流對(duì)象)的組合。當(dāng)輸入操作成功,(!cin)返回零值;如輸入操作失敗,則(!cin)返回非零值。(!cin)的功能詳見(jiàn)第八章 B1.2.4 緩沖輸入流”例5后的解釋。附錄十九是多個(gè)地方拋出的相同內(nèi)容的異常在同一個(gè)catch程序塊內(nèi)處理的另一個(gè)例子。還有一種格式catch ()可用于捕獲各類(lèi)異常,或用于捕獲其它c(diǎn)atch ()格式所不能捕獲的異常。有興趣者可參閱附錄二十。C+異異常處理機(jī)制可簡(jiǎn)敘如下:1 .如果try塊中沒(méi)有拋出異
37、常,則所有與try塊相關(guān)的catch塊將被忽略,程序跳過(guò) 所有catch塊后繼續(xù)運(yùn)行。2 . catch塊一般位于try塊之后。如果try塊中拋出異常,try塊中的剩余語(yǔ)句將被跳 過(guò)而忽略。程序轉(zhuǎn)至其參數(shù)類(lèi)型與異常類(lèi)型相匹配的catch塊中,由其處理該異常。執(zhí)行完畢后,跳過(guò)其它c(diǎn)atch塊,再執(zhí)行所有catch塊以后的其它語(yǔ)句。3 .如果沒(méi)有其參數(shù)類(lèi)型與異常類(lèi)型相匹配的catch塊,則由catch ()塊處理該異常。7.3 用干處理異常的類(lèi)7.3.1 系統(tǒng)提供的異常類(lèi)exception_2.cp葉拋出異常的語(yǔ)句是:if ( divisor = 0 ) throw exception();而其運(yùn)
38、行結(jié)果顯示異常性質(zhì)為 Unknown exception而exception_3.cpp(未顯示整個(gè)程序)中拋出異常的語(yǔ)句是 :if ( divisor = 0 )throw exception( "divide-by-zero exception");而其運(yùn)行結(jié)果顯示異常性質(zhì)為divide-by-zero exception這是建立異常類(lèi)的對(duì)象的兩種不同方式。這是什么異常類(lèi)?先看一下系統(tǒng)的異常類(lèi)。系統(tǒng)在頭文件exception (沒(méi)有exception.)中聲明了用于處理異常的類(lèi) exception該類(lèi)的接口如下: class exception public:excep
39、tion。;exception(const char* &);exception(const exception&);exception& operator= (const exception&);virtual exception();virtual char* what( ) const; private:char* _m_what;int _m_doFree;一一exception_2.cpp中拋出異常的語(yǔ)句是:if ( divisor = 0 ) throw exception();它七建立對(duì)象時(shí)調(diào)用構(gòu)造函數(shù) exception。,沒(méi)有任何初始化參數(shù)。而
40、字符 用“Unknown exceptions"則是該異常類(lèi)構(gòu)造函數(shù)的缺省參數(shù)。而exception_3.cp葉拋出異常的語(yǔ)句是:if ( divisor = 0 )throw exception( "divide-by-zero exception");它在建立對(duì)象時(shí)調(diào)用重載的構(gòu)造函數(shù) exception ( const char* & ),將字符串 "divide-by-zero exception"用作初始化參數(shù), 寫(xiě)入 exception : _m_what字符串 中。而以后主程序中調(diào)用該對(duì)象 ex的成員函數(shù)ex.what()時(shí)
41、,加在運(yùn)行結(jié)果中 顯示該字符串,指出異常性質(zhì)為divide-by-zero exceptions用戶除使用系統(tǒng)的異常類(lèi)之外,也可自己定義該系統(tǒng)異常類(lèi)class exception的派生類(lèi)。例1用戶自己定義系統(tǒng)class exception勺派生異常類(lèi)/ exception_derived_loop_1.cpp/ derived class of system class exception#include <iostream.h>#include <exception> double denominator;class Except_derive : public ex
42、ception一char *message; public:Except_derive(char * ptr) message = ptr; const char * what( ) const return message; void handling ( Xcout << "Enter denominator" (分母)again :"cin >> denominator; ;void main()double numerator;bool flag = true;cout << "Enter two data :
43、"cin >> numerator >> denominator;while ( flag )tryif ( denominator = 0 ) throw Except derive( "divide by zero!"); cout<< "The quotient is: " <<(numerator/denominator)<<endl;flag = false;catch ( Except derive ex ) / exception handlercout <<
44、 "Exception : " << ex.what( ) << 'n'ex.handling (); /while/* Results:Enter two data : 4 0Exception : divide by zero!Enter denominator" (分母)again : 8The quotient is: 0.5*/以上程序中使用了循環(huán)方式,當(dāng)出現(xiàn)異常時(shí)可循環(huán)運(yùn)行,以便要求用戶再次輸 入正確數(shù)據(jù)。只當(dāng)輸入的兩個(gè)數(shù)據(jù)都正確時(shí),程序才給出運(yùn)算結(jié)果并正常結(jié)束。7.3.2 用戶自定義異常類(lèi)上例只說(shuō)明用戶可定義系
45、統(tǒng)異常類(lèi)的派生類(lèi),但并無(wú)實(shí)際意義。還不如用戶 自己定義異常類(lèi)。如下例:例1在給定溫度條件下進(jìn)行除法運(yùn)算。先檢查溫度,如溫度過(guò)高或過(guò)低,則調(diào) 整溫度至給定范圍。然后在除法運(yùn)算中檢查零除數(shù)。異常類(lèi)的基類(lèi)用于處理零除 數(shù);異常類(lèi)的派生類(lèi)則用于處理溫度過(guò)高或溫度過(guò)低,并能自動(dòng)地每次將溫度調(diào) 整10度。/ exception_derived_loop_2.cpp/ user-defined class except and its derived classes#include <iostream.h>#define MAX_T 28#define MIN_T 16int temperatu
46、re;double denominator;class exceptchar *message;public:except (char * ptr) message = ptr; const char * what( ) const return message; virtual void handling ( ) cout << "Enter a non-zero denominator again :"cin >> denominator; void action ( ) cout << "Exception : "
47、; << what( ) << 'n'handling" ;class except_derive : public except一public:except_derive(char * ptr) : except (ptr) virtual void handling ( ) if ( temperature > MAX_T )cout <<“啟動(dòng)溫控系統(tǒng),將溫度降至 "<< (temperature -= 10) << endl; elsecout << “啟動(dòng)溫控系統(tǒng),將溫度
48、升至"<< (temperature += 10) << endl;double quotient( double numerator, double denominator ) if ( denominator = 0 ) throw except( "divide by zero!");return numerator / denominator;void main() double numerator, result;bool flag = true;char * mes_low = "Temperature too low
49、!"char * mes_high = "Temperature too high!"cout << "Measured temperature :"cin >> temperature;cout << "Enter numerator and denominator :"cin >> numerator >> denominator;while ( flag ) try if ( temperature > MAX_T )|( temperature <
50、; MIN_T )throw except derive( temperature > MAX T )?( mes high ):( mes low ); result = quotient ( numerator, denominator );cout << "The quotient is: " << result << endl;flag = false;/ The following order should not be reversed catch ( except derive ex ) ex.action( ); c
51、atch ( except ex )ex.action( ); / while/* At least three kinds of results:(1)Measured temperature : 20Enter numerator and denominator : 2 4The quotient is: 0.5(2)Measured temperature : 40Enter numerator and denominator : 4 8Exception : Temperature too high!啟動(dòng)溫控系統(tǒng),將溫度降至30Exception : Temperature too h
52、igh!啟動(dòng)溫控系統(tǒng),將溫度降至20The quotient is: 0.5(3)Measured temperature : 5Enter numerator and denominator : 4 0Exception : Temperature too low!啟動(dòng)溫控系統(tǒng),將溫度升至15Exception : Temperature too low!啟動(dòng)溫控系統(tǒng),將溫度升至25Exception : divide by zero!Enter a non-zero denominator again : 4The quotient is: 1*/當(dāng)以上程序中出現(xiàn)異常時(shí),任何一個(gè)捕獲塊都調(diào)
53、用基類(lèi)的 action( ) ,而此action( )函數(shù)能夠根據(jù)不同對(duì)象指針來(lái)調(diào)用相應(yīng)的虛函數(shù)handling( ), 實(shí)現(xiàn)第五章中所述“多態(tài)性”中的“派生類(lèi)成員函數(shù)的定向調(diào)用” 。另外,同一個(gè)派生類(lèi)同時(shí)用于處理溫度過(guò)高或過(guò)低,并區(qū)別地采取相應(yīng)措施。上面程序中,捕獲程序塊的順序不能顛倒為:catch ( except ex )ex.action( ); catch ( except_derive ex ) ex.action( ); 這時(shí)編譯系統(tǒng)將給出警告為:warning: 'class except_derive' is caught by base class (
54、9;class except')這樣一來(lái),其運(yùn)行結(jié)果將不正確,成為:(2)Measured temperature : 40Enter numerator and denominator : 4 8Exception : Temperature too high!Enter a non-zero denominator again : 4Exception : Temperature too high!Enter a non-zero denominator again : 2Exception : Temperature too high!Enter a non-zero denom
55、inator again :這是因?yàn)榈谝粋€(gè)捕獲程序塊也能捕獲異常派生類(lèi)的對(duì)象,從而導(dǎo)致出錯(cuò)。為何第一個(gè)捕獲程序塊也能捕獲異常派生類(lèi)的對(duì)象,但卻又給出錯(cuò)誤運(yùn)行結(jié)果?見(jiàn)下例: 例 2 形參為基類(lèi)對(duì)象的函數(shù)所使用實(shí)參為派生類(lèi)對(duì)象時(shí)的錯(cuò)誤/ obj_inh_1.cpp/ To show object of base class can't be inherited#include <iostream.h>class Pointdouble x, y;public:Point (double i, double j) x=i; y=j; virtual double Area( )
56、const return 0; ;class Rectangle : public Pointdouble w, h;public:Rectangle (double i, double j, double k, double l):Point (i, j) w=k; h=l; double Area( ) const return w*h; ;void fun(Point s)cout<<s.Area( )<<endl;void main()Point p (5, 6);Rectangle rec (3.5, 15.2, 5, 28);cout<<&quo
57、t;Area of Point is :"fun (p);cout<<"Area of Rectangle is :"fun (rec);/* Result:Area of Point is : 0Area of Rectangle is : 0 (當(dāng)函數(shù)形參是對(duì)象而非對(duì)象指針時(shí),無(wú)法調(diào)用派生類(lèi)部 分的虛函數(shù))*/程序中fun()的形參是基類(lèi)class Poin田勺對(duì)象,但它也能使用派生類(lèi)對(duì)象作為 實(shí)參,即fun (rec)。但因其形參已定義為基類(lèi)對(duì)象,因此函數(shù)體內(nèi)的s.Area()只能調(diào)用基類(lèi)的Area()函數(shù),得出錯(cuò)誤的運(yùn)行結(jié)果。此處 fun (r
58、ec)是合法的但卻錯(cuò) 誤的。因止匕,在exception_derived_loop_2.cppl序中,如錯(cuò)誤地將catch ( except ex ) ex.action( ); 放置于前,則它既會(huì)捕獲異常基類(lèi)又會(huì)捕獲異常派生類(lèi)的對(duì)象。而在捕獲異常派 生類(lèi)對(duì)象時(shí),將導(dǎo)致錯(cuò)誤的運(yùn)行結(jié)果。因此它也是是合法的但卻錯(cuò)誤的。7.3.3 異常類(lèi)基類(lèi)指針和引用的繼承以上 *.3.2"用戶自定義異常類(lèi)”例1的exception_derived_loop_2.cp沸序 中,為了捕獲兩個(gè)不同類(lèi)(基類(lèi)和派生類(lèi))的對(duì)象,使用兩1caich程7塊,即:catch ( except_derive ex ) ex
59、.action( ); catch ( except ex ) ex.action( ); 這兩個(gè)程序塊的形參都是異常類(lèi)的對(duì)象。能否合并為一個(gè),例如catch()程序塊?可以!但此合并后的程序塊無(wú)法捕獲對(duì)象名稱(chēng),也就無(wú)法區(qū)別并調(diào)用相應(yīng)類(lèi) 的對(duì)象的虛函數(shù)handling(),因這涉及基類(lèi)對(duì)象的繼承問(wèn)題。第五章中曾提到, 函數(shù)的“按數(shù)值調(diào)用”中,派生類(lèi)對(duì)象無(wú)法繼承基類(lèi)對(duì)象,但卻能繼承基類(lèi)對(duì)象 的指針和引用。因此須求助于基類(lèi)對(duì)象指針或引用。所以為了合并這兩個(gè) catch 程序塊,必須使用異常類(lèi)基類(lèi)的指針或引用而不是基類(lèi)對(duì)象本身。如下:例1異常類(lèi)基類(lèi)指針的繼承/ exception_derived_l
60、oop_3.cpp/ user-defined class except and its derived classes/ 和 exception_derived_loop_2.cppf 同之處用下戈U線標(biāo)出 #include <iostream.h>#define MAX_T 28#define MIN_T 16 int temperature; double denominator; class exceptchar *message;public:except (char * ptr) message = ptr; const char * what( ) const return message; virtual void handling ( ) cout << "Enter a non-zero denominator again :"cin >> denominator; void action ( ) cout << "Exception : " << what( ) << 'n
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 動(dòng)物剪紙美術(shù)課程設(shè)計(jì)
- 汽油機(jī)優(yōu)化課程設(shè)計(jì)
- 青少年社會(huì)工作課程設(shè)計(jì)
- 精課程設(shè)計(jì)留甲醇和水
- 小貸公司催收方案
- 有關(guān)眼科醫(yī)院的愛(ài)眼日活動(dòng)策劃方案
- 公司呆壞賬處理制度
- 綠茶的制作課程設(shè)計(jì)
- 課課程設(shè)計(jì)選題背景
- 專(zhuān)科文學(xué):探索與創(chuàng)新
- 職工心理健康調(diào)研報(bào)告
- 數(shù)控畢業(yè)設(shè)計(jì)范文樣本
- 售后服務(wù)的重要價(jià)值
- 2024年道路交通安全法理論考試真題
- 車(chē)隊(duì)年度工作計(jì)劃
- 2024AIGC視頻生成:走向AI創(chuàng)生時(shí)代:視頻生成的技術(shù)演進(jìn)、范式重塑與商業(yè)化路徑探索
- 素養(yǎng)本位下的高中數(shù)學(xué)大單元整體教學(xué)設(shè)計(jì)實(shí)踐研究
- 溫泉設(shè)計(jì)方案方案
- 四年級(jí)美術(shù) 《飛天》【全國(guó)一等獎(jiǎng)】
- 2024中考數(shù)學(xué)一輪復(fù)習(xí)專(zhuān)題11 二次函數(shù)的綜合應(yīng)用
- 2024年國(guó)能包神鐵路集團(tuán)有限責(zé)任公司招聘筆試參考題庫(kù)含答案解析
評(píng)論
0/150
提交評(píng)論