![譚浩強《C++程序設(shè)計》課件 第14章.ppt_第1頁](http://file1.renrendoc.com/fileroot2/2020-1/20/9970fab3-c9bc-408d-a4ce-8a406e4c9c09/9970fab3-c9bc-408d-a4ce-8a406e4c9c091.gif)
![譚浩強《C++程序設(shè)計》課件 第14章.ppt_第2頁](http://file1.renrendoc.com/fileroot2/2020-1/20/9970fab3-c9bc-408d-a4ce-8a406e4c9c09/9970fab3-c9bc-408d-a4ce-8a406e4c9c092.gif)
![譚浩強《C++程序設(shè)計》課件 第14章.ppt_第3頁](http://file1.renrendoc.com/fileroot2/2020-1/20/9970fab3-c9bc-408d-a4ce-8a406e4c9c09/9970fab3-c9bc-408d-a4ce-8a406e4c9c093.gif)
![譚浩強《C++程序設(shè)計》課件 第14章.ppt_第4頁](http://file1.renrendoc.com/fileroot2/2020-1/20/9970fab3-c9bc-408d-a4ce-8a406e4c9c09/9970fab3-c9bc-408d-a4ce-8a406e4c9c094.gif)
![譚浩強《C++程序設(shè)計》課件 第14章.ppt_第5頁](http://file1.renrendoc.com/fileroot2/2020-1/20/9970fab3-c9bc-408d-a4ce-8a406e4c9c09/9970fab3-c9bc-408d-a4ce-8a406e4c9c095.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第14章 C+工具,14.1 異常處理 14.2 命名空間 14.3 使用早期的函數(shù)庫,在C+發(fā)展的后期,有時C+編譯系統(tǒng)根據(jù)實際工作的需要,增加了一些功能,作為工具來使用,其中主要有模板(包括函數(shù)模板和類模板)、異常處理、命名空間和運行時類型識別,以幫助程序設(shè)計人員更方便地進行程序的設(shè)計和調(diào)試工作。1997年ANSI C+委員會將它們納入了ANSI C+標準,建議所有的C+編譯系統(tǒng)都能實現(xiàn)這些功能。這些工具是非常有用的,C+的使用者應(yīng)當盡量使用這些工具。,程序編制者不僅要考慮程序沒有錯誤的理想情況,更要考慮程序存在錯誤時的情況,應(yīng)該能夠盡快地發(fā)現(xiàn)錯誤,消除錯誤。 程序中常見的錯誤有兩大類:
2、語法錯誤和運行錯誤。在編譯時,編譯系統(tǒng)能發(fā)現(xiàn)程序中的語法錯誤。 有的程序雖然能通過編譯,也能投入運行。但是在運行過程中會出現(xiàn)異常,得不到正確的運行結(jié)果,甚至導致程序不正常終止,或出現(xiàn)死機現(xiàn)象。這類錯誤比較隱蔽,不易被發(fā)現(xiàn),往往耗費許多時間和精力。這成為程序調(diào)試中的一個難點。,14.1 異常處理 14.1.1 異常處理的任務(wù),在設(shè)計程序時,應(yīng)當事先分析程序運行時可能出現(xiàn)的各種意外的情況,并且分別制訂出相應(yīng)的處理方法,這就是程序的異常處理的任務(wù)。 在運行沒有異常處理的程序時,如果運行情況出現(xiàn)異常,由于程序本身不能處理,程序只能終止運行。如果在程序中設(shè)置了異常處理機制,則在運行情況出現(xiàn)異常時,由于程
3、序本身已規(guī)定了處理的方法,于是程序的流程就轉(zhuǎn)到異常處理代碼段處理。用戶可以指定進行任何的處理。 需要說明,只要出現(xiàn)與人們期望的情況不同,都可以認為是異常,并對它進行異常處理。因此,所謂異常處理指的是對運行時出現(xiàn)的差錯以及其他例外情況的處理。,在一個小的程序中,可以用比較簡單的方法處理異常。但是在一個大的系統(tǒng)中,如果在每一個函數(shù)中都設(shè)置處理異常的程序段,會使程序過于復雜和龐大。因此,C+采取的辦法是: 如果在執(zhí)行一個函數(shù)過程中出現(xiàn)異常,可以不在本函數(shù)中立即處理,而是發(fā)出一個信息,傳給它的上一級(即調(diào)用它的函數(shù)),它的上級捕捉到這個信息后進行處理。如果上一級的函數(shù)也不能處理,就再傳給其上一級,由其
4、上一級處理。如此逐級上送,如果到最高一級還無法處理,最后只好異常終止程序的執(zhí)行。,14.1.2 異常處理的方法,這樣做使異常的發(fā)現(xiàn)與處理不由同一函數(shù)來完成。好處是使底層的函數(shù)專門用于解決實際任務(wù),而不必再承擔處理異常的任務(wù),以減輕底層函數(shù)的負擔,而把處理異常的任務(wù)上移到某一層去處理。這樣可以提高效率。 C+處理異常的機制是由3個部分組成的,即檢查(try)、拋出(throw)和捕捉(catch)。把需要檢查的語句放在try塊中,throw用來當出現(xiàn)異常時發(fā)出一個異常信息,而catch則用來捕捉異常信息,如果捕捉到了異常信息,就處理它。,例14.1 給出三角形的三邊a,b,c,求三角形的面積。只
5、有a+bc,b+ca,c+ab時才能構(gòu)成三角形。設(shè)置異常處理,對不符合三角形條件的輸出警告信息,不予計算。 先寫出沒有異常處理時的程序: #include #include using namespace std; int main( ) double triangle(double,double,double); double a,b,c; cinabc; while(a0 , double triangle(double a,double b,double c) double area; double s=(a+b+c)/2; area=sqrt(s*(s-a)*(s-b)*(s-c);
6、return area; 運行情況如下: 6 5 4(輸入a,b,c的值) 9.92157 (輸出三角形的面積) 1 1.5 2 (輸入a,b,c的值) 0.726184 (輸出三角形的面積) 1 2 1 (輸入a,b,c的值) 0 (輸出三角形的面積,此結(jié)果顯然不對,因為不是三角形) 1 0 6 (輸入a,b,c的值) (結(jié)束),修改程序,在函數(shù)traingle中對三角形條件進行檢查,如果不符合三角形條件,就拋出一個異常信息,在主函數(shù)中的try-catch塊中調(diào)用traingle函數(shù),檢測有無異常信息,并作相應(yīng)處理。修改后的程序如下: #include #include using name
7、space std; void main( ) double triangle(double,double,double); double a,b,c; cinabc; try/在try塊中包含要檢查的函數(shù) while(a0 ,catch(double) /用catch捕捉異常信息并作相應(yīng)處理 couta=a,b=b,c=c,that is not a triangle!endl; coutendendl; double triangle(double a,double b,double c) /計算三角形的面積的函數(shù) double s=(a+b+c)/2; if (a+b=c|b+c=a|c
8、+a=b) throw a; /當不符合三角形條件拋出異常信息 return sqrt(s*(s-a)*(s-b)*(s-c); 程序運行結(jié)果如下: 6 5 4(輸入a,b,c的值) 9.92157 (計算出三角形的面積) 1 1.5 2 (輸入a,b,c的值) 0.726184 (計算出三角形的面積) 1 2 1 (輸入a,b,c的值) a=1,b=2,c=1, that is not a triangle! (異常處理) end,現(xiàn)在結(jié)合程序分析怎樣進行異常處理。 (1) 首先把可能出現(xiàn)異常的、需要檢查的語句或程序段放在try后面的花括號中。 (2) 程序開始運行后,按正常的順序執(zhí)行到tr
9、y塊,開始執(zhí)行try塊中花括號內(nèi)的語句。如果在執(zhí)行try塊內(nèi)的語句過程中沒有發(fā)生異常,則catch子句不起作用,流程轉(zhuǎn)到catch子句后面的語句繼續(xù)執(zhí)行。 (3) 如果在執(zhí)行try塊內(nèi)的語句(包括其所調(diào)用的函數(shù))過程中發(fā)生異常,則throw運算符拋出一個異常信息。throw拋出異常信息后,流程立即離開本函數(shù),轉(zhuǎn)到其上一級的函數(shù)(main 函數(shù))。 throw拋出什么樣的數(shù)據(jù)由程序設(shè)計者自定,可以是任何類型的數(shù)據(jù)。,(4) 這個異常信息提供給try-catch結(jié)構(gòu),系統(tǒng)會尋找與之匹配的catch子句。 (5) 在進行異常處理后,程序并不會自動終止,繼續(xù)執(zhí)行catch子句后面的語句。 由于catc
10、h子句是用來處理異常信息的,往往被稱為catch異常處理塊或catch異常處理器。,下面講述異常處理的語法。 throw語句一般是由throw運算符和一個數(shù)據(jù)組成的,其形式為 throw 表達式; try-catch的結(jié)構(gòu)為 try 被檢查的語句 catch(異常信息類型 變量名) 進行異常處理的語句,說明: (1) 被檢測的函數(shù)必須放在try塊中,否則不起作用。 (2) try塊和catch塊作為一個整體出現(xiàn),catch塊是try-catch結(jié)構(gòu)中的一部分,必須緊跟在try塊之后,不能單獨使用,在二者之間也不能插入其他語句。但是在一個try-catch結(jié)構(gòu)中,可以只有try塊而無catch塊
11、。即在本函數(shù)中只檢查而不處理,把catch處理塊放在其他函數(shù)中。 (3) try和catch塊中必須有用花括號括起來的復合語句,即使花括號內(nèi)只有一個語句,也不能省略花括號。 (4) 一個try-catch結(jié)構(gòu)中只能有一個try塊,但卻可以有多個catch塊,以便與不同的異常信息匹配。,(5) catch后面的圓括號中,一般只寫異常信息的類型名, 如 catch(double) catch只檢查所捕獲異常信息的類型,而不檢查它們的值。因此如果需要檢測多個不同的異常信息,應(yīng)當由throw拋出不同類型的異常信息。 異常信息可以是C+系統(tǒng)預定義的標準類型,也可以是用戶自定義的類型(如結(jié)構(gòu)體或類)。如果
12、由throw拋出的信息屬于該類型或其子類型,則catch與throw二者匹配,catch捕獲該異常信息。 catch還可以有另外一種寫法,即除了指定類型名外,還指定變量名,如 catch(double d),此時如果throw拋出的異常信息是double型的變量a,則catch在捕獲異常信息a的同時,還使d獲得a的值,或者說d得到a的一個拷貝。什么時候需要這樣做呢?有時希望在捕獲異常信息時,還能利用throw拋出的值,如 catch(double d) coutthrow d; 這時會輸出d的值(也就是a值)。當拋出的是類對象時,有時希望在catch塊中顯示該對象中的某些信息。這時就需要在ca
13、tch的參數(shù)中寫出變量名(類對象名)。 (6) 如果在catch子句中沒有指定異常信息的類型,而用了刪節(jié)號“”,則表示它可以捕捉任何類型的異常信息,如,catch() coutOKendl; 它能捕捉所有類型的異常信息,并輸出OK。 這種catch子句應(yīng)放在trycatch結(jié)構(gòu)中的最后,相當于“其他”。如果把它作為第一個catch子句,則后面的catch子句都不起作用。 (7) trycatch結(jié)構(gòu)可以與throw出現(xiàn)在同一個函數(shù)中,也可以不在同一函數(shù)中。當throw拋出異常信息后,首先在本函數(shù)中尋找與之匹配的catch,如果在本函數(shù)中無trycatch結(jié)構(gòu)或找不到與之匹配的catch,就轉(zhuǎn)到
14、離開出現(xiàn)異常最近的trycatch結(jié)構(gòu)去處理。,(8) 在某些情況下,在throw語句中可以不包括表達式,如 throw; 表示“我不處理這個異常,請上級處理”。 (9) 如果throw拋出的異常信息找不到與之匹配的catch塊,那么系統(tǒng)就會調(diào)用一個系統(tǒng)函數(shù)terminate,使程序終止運行。 例14.2 在函數(shù)嵌套的情況下檢測異常處理。 這是一個簡單的例子,用來說明在try塊中有函數(shù)嵌套調(diào)用的情況下拋出異常和捕捉異常的情況。請自己先分析以下程序。,#include using namespace std; int main( ) void f1( ); try f1( );/調(diào)用f1( )
15、catch(double) coutOK0!endl; coutend0endl; return 0; void f1( ) void f2( ); try f2( ); /調(diào)用f2( ) catch(char) coutOK1!; coutend1endl; ,void f2( ) void f3( ); try f3( ); /調(diào)用f3( ) catch(int) coutOk2!endl; coutend2endl; void f3( ) double a=0; try throw a; /拋出double類型異常信息 catch(float) coutOK3!endl; coutend
16、3endl; ,分3種情況分析運行情況: (1) 執(zhí)行上面的程序。圖14.1為有函數(shù)嵌套時異常處理示意圖。 圖14.1 程序運行結(jié)果如下: OK0!(在主函數(shù)中捕獲異常) end0 (執(zhí)行主函數(shù)中最后一個語句時的輸出),(2) 如果將f3函數(shù)中的catch子句改為catch(double),而程序中其他部分不變,則程序運行結(jié)果如下: OK3!(在f3函數(shù)中捕獲異常) end3 (執(zhí)行f3函數(shù)中最后一個語句時的輸出) end2 (執(zhí)行f2函數(shù)中最后一個語句時的輸出) end1 (執(zhí)行f1函數(shù)中最后一個語句時的輸出) end0 (執(zhí)行主函數(shù)中最后一個語句時的輸出) (3) 如果在此基礎(chǔ)上再將f3函
17、數(shù)中的catch塊改為 catch(double) coutOK3!endl;throw; 程序運行結(jié)果如下: OK3!(在f3函數(shù)中捕獲異常) OK0! (在主函數(shù)中捕獲異常) end0 (執(zhí)行主函數(shù)中最后一個語句時的輸出),為便于閱讀程序,使用戶在看程序時能夠知道所用的函數(shù)是否會拋出異常信息以及異常信息可能的類型,C+允許在聲明函數(shù)時列出可能拋出的異常類型,如可以將例14.1中第二個程序的第3行改寫為 double triangle(double,double,double) throw(double); 表示triangle函數(shù)只能拋出double類型的異常信息。如果寫成 double
18、triangle(double,double,double) throw(int,double,float,char); 則表示triangle函數(shù)可以拋出int,double,float或char類型的異常信息。異常指定是函數(shù)聲明的一部分,必須同時出現(xiàn)在函數(shù)聲明和函數(shù)定義的首行中,否則在進行函數(shù)的另一次聲明時,編譯系統(tǒng)會報告“類型不匹配”。,14.1.3 在函數(shù)聲明中進行異常情況指定,如果在聲明函數(shù)時未列出可能拋出的異常類型,則該函數(shù)可以拋出任何類型的異常信息。如例14.1中第2個程序中所表示的那樣。 如果想聲明一個不能拋出異常的函數(shù),可以寫成以下形式: double triangle(do
19、uble,double,double) throw();/throw無參數(shù) 這時即使在函數(shù)執(zhí)行過程中出現(xiàn)了throw語句,實際上也并不執(zhí)行throw語句,并不拋出任何異常信息,程序?qū)⒎钦=K止。,如果在try塊(或try塊中調(diào)用的函數(shù))中定義了類對象,在建立該對象時要調(diào)用構(gòu)造函數(shù)。在執(zhí)行try塊 (包括在try塊中調(diào)用其他函數(shù)) 的過程中如果發(fā)生了異常,此時流程立即離開try塊。這樣流程就有可能離開該對象的作用域而轉(zhuǎn)到其他函數(shù),因而應(yīng)當事先做好結(jié)束對象前的清理工作,C+的異常處理機制會在throw拋出異常信息被catch捕獲時,對有關(guān)的局部對象進行析構(gòu)(調(diào)用類對象的析構(gòu)函數(shù)), 析構(gòu)對象的順序
20、與構(gòu)造的順序相反,然后執(zhí)行與異常信息匹配的catch塊中的語句。,14.1.4 在異常處理中處理析構(gòu)函數(shù),例14.3 在異常處理中處理析構(gòu)函數(shù)。 這是一個為說明在異常處理中調(diào)用析構(gòu)函數(shù)的示例,為了清晰地表示流程,程序中加入了一些cout語句,輸出有關(guān)的信息,以便對照結(jié)果分析程序。 #include #include using namespace std; class Student public: Student(int n,string nam)/定義構(gòu)造函數(shù) coutconstructor-nendl; num=n;name=nam; Student( )coutdestructor-n
21、umendl;/定義析構(gòu)函數(shù) void get_data( ); /成員函數(shù)聲明 private: int num; string name; ;,void Student:get_data( ) /定義成員函數(shù) if(num=0) throw num; /如num=0,拋出int型變量num else coutnum nameendl; /若num0,輸出num,name coutin get_data()endl; /輸出信息,表示目前在get_data函數(shù)中 void fun( ) Student stud1(1101,Tan); /建立對象stud1 stud1.get_data( )
22、; /調(diào)用stud1的get_data函數(shù) Student stud2(0,Li); /建立對象stud2 stud2.get_data( ); /調(diào)用stud2的get_data函數(shù) int main( ) coutmain beginendl; /表示主函數(shù)開始了 coutcall fun( )endl; /表示調(diào)用fun函數(shù) try fun( ); /調(diào)用fun函數(shù),catch(int n) coutnum=n,error!endl; /表示num=0出錯 coutmain endendl; /表示主函數(shù)結(jié)束 return 0; 程序運行結(jié)果如下: main begin call fun
23、( ) constructor-1101 1101 tan in get_data() constructor-0 destructor-0 destructor-1101 num=0,error! main end,在學習本書前面各章時,已經(jīng)多次看到在程序中用了以下語句: using namespace std; 這就是使用了命名空間std。在本節(jié)中將對它作較詳細的介紹。,14.2 命名空間,命名空間是ANSI C+引入的可以由用戶命名的作用域,用來處理程序中常見的同名沖突。 在C語言中定義了3個層次的作用域,即文件(編譯單元) 、函數(shù)和復合語句。C+又引入了類作用域,類是出現(xiàn)在文件內(nèi)的。在
24、不同的作用域中可以定義相同名字的變量,互不干擾,系統(tǒng)能夠區(qū)別它們。 下面先簡單分析一下作用域的作用,然后討論命名空間的作用。 如果在文件中定義了兩個類,在這兩個類中可以有同名的函數(shù)。在引用時,為了區(qū)別,應(yīng)該加上類名作為限定,如,14.2.1 為什么需要命名空間,class A/聲明A類 public: void fun1( ); /聲明A類中的fun1函數(shù) private: int i; ; void A:fun1( ) /定義A類中的fun1函數(shù) / class B /聲明B類 public: void fun1( ); /B類中也有fun1函數(shù) void fun2( ); ; void B
25、:fun1( ) /定義B類中的fun1函數(shù) / ,這樣不會發(fā)生混淆。 在文件中可以定義全局變量(global variable),它的作用域是整個程序。如果在文件A中定義了一個變量a int a=3; 在文件B中可以再定義一個變量a int a=5; 在分別對文件A和文件B進行編譯時不會有問題。但是,如果一個程序包括文件A和文件B,那么在進行連接時,會報告出錯,因為在同一個程序中有兩個同名的變量,認為是對變量的重復定義。問題在于全局變量的作用域是整個程序,在同一作用域中不應(yīng)有兩個或多個同名的實體(entity),包括變量、函數(shù)和類等。,可以通過extern聲明同一程序中的兩個文件中的同名變量
26、是同一個變量。如果在文件B中有以下聲明: extern int a; 表示文件B中的變量a是在其他文件中已定義的變量。由于有此聲明,在程序編譯和連接后,文件A的變量a的作用域擴展到了文件B。如果在文件B中不再對a賦值,則在文件B中用以下語句輸出的是文件A中變量 a的值: couta;/得到a的值為3 在簡單的程序設(shè)計中,只要人們小心注意,可以爭取不發(fā)生錯誤。但是,一個大型的應(yīng)用軟件,往往不是由一個人獨立完成的,假如不同的人分別定義了類,放在不同的頭文件中,在主文件(包含主函數(shù)的文件)需要用這些類時,,就用#include命令行將這些頭文件包含進來。由于各頭文件是由不同的人設(shè)計的,有可能在不同的
27、頭文件中用了相同的名字來命名所定義的類或函數(shù)。這樣在程序中就會出現(xiàn)名字沖突。 例14.4 名字沖突。 程序員甲在頭文件header1.h中定義了類Student和函數(shù)fun。 /header1.h (頭文件1,設(shè)其文件名為cc14-4-h1.h) #include #include using namespace std; class Student/聲明Student類 public: Student(int n,string nam,char s) num=n;name=nam;sex=s; void get_data( ); private:,int num; string name;
28、char sex; ; void Student:get_data( ) /成員函數(shù)定義 cout #include cc14-4-h1.h /注意要用雙引號,因為文件一般是放在用戶目錄中的 using namespace std; int main( ) Student stud1(101,Wang,18); /定義類對象stud1 stud1.get_data( ); coutfun(5,3)endl; return 0; ,程序能正常運行,輸出為 101 Wang 18 2.82843 如果程序員乙寫了頭文件header2.h,在其中除了定義其他類以外,還定義了類Student和函數(shù)fu
29、n,但其內(nèi)容與頭文件header1.h中的Student和函數(shù)fun有所不同。 /header2.h (頭文件2,設(shè)其文件名為cc14-4-h2.h) #include #include using namespace std; class Student/聲明Student類 public: Student(int n,string nam,char s) /參數(shù)與header1中的student不同 num=n;name=nam;sex=s; void get_data( );,private: int num; string name; char sex; /此項與header1不同 ;
30、 void Student:get_data( ) /成員函數(shù)定義 coutnum name sexendl; double fun(double a,double b) /定義全局函數(shù) return sqrt(a-b); /返回值與header1中的fun函數(shù)不同 /頭文件2中可能還有其他內(nèi)容 假如主程序員在其程序中要用到header1.h中的Student和函數(shù)fun,因而在程序中包含了頭文件header1.h,同時要用到頭文件header2.h中的一些內(nèi)容,因而在程序中又包含了頭文件header2.h。如果主文件(包含主函數(shù)的文件)如下:,/main file #include #inc
31、lude cc14-4-h1.h/包含頭文件1 #include cc14-4-h2.h /包含頭文件2 using namespace std; int main( ) Student stud1(101,Wang,18); stud1.get_data(); coutfun(5,3)endl; return 0; 這時程序編譯就會出錯。 因為在預編譯后,頭文件中的內(nèi)容取代了對應(yīng)的#include命令行,這樣就在同一個程序文件中出現(xiàn)了兩個Student類和兩個fun函數(shù),顯然是重復定義,這就是名字沖突,即在同一個作用域中有兩個或多個同名的實體。,不僅如此,在程序中還往往需要引用一些庫,為此需
32、要包含有關(guān)的頭文件。如果在這些庫中包含有與程序的全局實體同名的實體,或者不同的庫中有相同的實體名,則在編譯時就會出現(xiàn)名字沖突。 為了避免這類問題的出現(xiàn),人們提出了許多方法,例如: 將實體的名字寫得長一些;把名字起得特殊一些,包括一些特殊的字符;由編譯系統(tǒng)提供的內(nèi)部全局標識符都用下劃線作為前綴,如_complex(),以避免與用戶命名的實體同名;由軟件開發(fā)商提供的實體的名字用特定的字符作為前綴。但是這樣的效果并不理想,而且增加了閱讀程序的難度,可讀性降低了。,C語言和早期的C+語言沒有提供有效的機制來解決這個問題,沒有使庫的提供者能夠建立自己的命名空間的工具。人們希望ANSI C+標準能夠解決這
33、個問題,提供一種機制、一種工具,使由庫的設(shè)計者命名的全局標識符能夠和程序的全局實體名以及其他庫的全局標識符區(qū)別開來。,為了解決上面這個問題,ANSI C+增加了命名空間(namespace)。所謂命名空間,實際上就是一個由程序設(shè)計者命名的內(nèi)存區(qū)域。程序設(shè)計者可以根據(jù)需要指定一些有名字的空間域,把一些全局實體分別放在各個命名空間中,從而與其他全局實體分隔開來。如 namespace ns1/指定命名空間ns1 int a; double b; 現(xiàn)在命名空間成員包括變量a和b,注意a和b仍然是全局變量,僅僅是把它們隱藏在指定的命名空間中而已。,14.2.2 什么是命名空間,如果在程序中要使用變量a
34、和b,必須加上命名空間名和作用域分辨符“:”,如ns1:a,ns1:b。這種用法稱為命名空間限定(qualified),這些名字(如ns1:a)稱為被限定名(qualified name)。C+中命名空間的作用類似于操作系統(tǒng)中的目錄和文件的關(guān)系。 命名空間的作用是建立一些互相分隔的作用域,把一些全局實體分隔開來,以免產(chǎn)生名字沖突。 可以根據(jù)需要設(shè)置許多個命名空間,每個命名空間名代表一個不同的命名空間域,不同的命名空間不能同名。這樣,可以把不同的庫中的實體放到不同的命名空間中。過去我們用的全局變量可以理解為全局命名空間,獨立于所有有名的命名空間之外,它是不需要用namespace聲明的,實際上是
35、由系統(tǒng)隱式聲明的,存在于每個程序之中。,在聲明一個命名空間時,花括號內(nèi)不僅可以包括變量,而且還可以包括以下類型: 變量(可以帶有初始化); 常量; 函數(shù)(可以是定義或聲明); 結(jié)構(gòu)體; 類; 模板; 命名空間(在一個命名空間中又定義一個命名空間,即嵌套的命名空間)。 例如,namespace ns1 const int RATE=0.08;/常量 double pay; /變量 double tax( ) /函數(shù) return a*RATE; namespace ns2 /嵌套的命名空間 int age; 如果想輸出命名空間ns1中成員的數(shù)據(jù),可以采用下面的方法: coutns1:RATEen
36、dl; coutns1:payendl; coutns1:tax()endl; coutns1:ns2:ageendl;/需要指定外層的和內(nèi)層的命名空間名,現(xiàn)在,對例14.4程序進行修改,使之能正確運行。 例14.5 利用命名空間來解決例14.4程序名字沖突問題。 修改兩個頭文件,把在頭文件中聲明的類分別放在兩個不同的命名空間中。 /header1.h (頭文件1) #include #include using namespace std; namespace ns1/聲明命名空間ns1 class Student /在命名空間ns1內(nèi)聲明Student類 public: Student(i
37、nt n,string nam,int a),14.2.3 使用命名空間解決名字沖突,num=n;name=nam;age=a; void get_data( ); private: int num; string name; int age; ; void Student:get_data() /定義成員函數(shù) cout #include ,using namespace std; namespace ns2 /聲明命名空間ns2 class Student public: Student(int n,string nam,char s) num=n;name=nam;sex=s; void
38、get_data( ); private: int num; char name20; char sex; ; void Student:get_data( ) coutnum name sexendl; double fun(double a,double b) return sqrt(a-b); ,/main file (主文件) #include #include cc14-5-h1.h /包含頭文件1 #include cc14-5-h2.h /包含頭文件2 using namespace std; int main( ) ns1:Student stud1(101,Wang,18);
39、 /用命名空間ns1中聲明的Student類定義stud1 stud1.get_data( ); /不要寫成ns1:stud1.get_data( ); coutns1:fun(5,3)endl; /調(diào)用命名空間ns1中的fun函數(shù) ns2:Student stud2(102,Li,f); /用命名空間ns2中聲明的Student類定義stud2 stud2.get_data( ); coutns2:fun(5,3)endl; /調(diào)用命名空間ns1中的fun函數(shù) return 0; ,程序能順利通過編譯,并得到以下運行結(jié)果: 101 Wang 18(對象stud1中的數(shù)據(jù)) 2.82843 (
40、5+3的開方值) 102 Li f (對象stud2中的數(shù)據(jù)) 1.41421 (5-3的開方值),在引用命名空間成員時,要用命名空間名和作用域分辨符對命名空間成員進行限定,以區(qū)別不同的命名空間中的同名標識符。即 命名空間名:命名空間成員名 這種方法是有效的,能保證所引用的實體有惟一的名字。但是如果命名空間名字比較長,尤其在有命名空間嵌套的情況下,為引用一個實體,需要寫很長的名字。在一個程序中可能要多次引用命名空間成員,就會感到很不方便。 為此,C+提供了一些機制,能簡化使用命名空間成員的手續(xù)。,14.2.4 使用命名空間成員的方法,(1) 使用命名空間別名 可以為命名空間起一個別名(name
41、space alias),用來代替較長的命名空間名。如 namespace Television/聲明命名空間,名為Television 可以用一個較短而易記的別名代替它。如 namespace TV = Television;/別名TV與原名Television等價 (2) 使用using 命名空間成員名 using后面的命名空間成員名必須是由命名空間限定的名字。例如 using ns1:Student; using聲明的有效范圍是從using語句開始到using所在的作用域結(jié)束。如果在以上的using語句之后有以下語句:,Student stud1(101,Wang,18);/此處的Stu
42、dent相當于ns1:Student 上面的語句相當于 ns1:Student stud1(101,Wang,18); 又如 using ns1:fun;/聲明其后出現(xiàn)的fun是屬于命名空間ns1中的fun coutfun(5,3)endl; /此處的fun函數(shù)相當于ns1:fun(5,3) 顯然,這可以避免在每一次引用命名空間成員時都用命名空間限定,使得引用命名空間成員方便易用。 但是要注意: 在同一作用域中用using聲明的不同命名空間的成員中不能有同名的成員。例如 using ns1:Student;/聲明其后出現(xiàn)的Student是命名空間ns1中的Student using ns2:S
43、tudent; /聲明其后出現(xiàn)的Student是命名空間ns2中的Student Student stud1; /請問此處的Student是哪個命名空間中的Student? 產(chǎn)生了二義性,編譯出錯。,(3) 使用using namespace 命名空間名 能否在程序中用一個語句就能一次聲明一個命名空間中的全部成員呢? C+提供了using namespace語句來實現(xiàn)這一目的。using namespace語句的一般格式為 using namespace命名空間名; 例如 using namespace ns1; 聲明了在本作用域中要用到命名空間ns1中的成員,在使用該命名空間的任何成員時都不
44、必用命名空間限定。如果在作了上面的聲明后有以下語句: Student stud1(101,Wang,18);/Student隱含指命名空間ns1中的Student coutfun(5,3)endl; /這里的fun函數(shù)是命名空間ns1中的fun函數(shù),在用using namespace聲明的作用域中,命名空間ns1的成員就好像在全局域聲明的一樣。因此可以不必用命名空間限定。顯然這樣的處理對寫程序比較方便。但是如果同時用using namespace聲明多個命名空間時,往往容易出錯。因此只有在使用命名空間數(shù)量很少,以及確保這些命名空間中沒有同名成員時才用using namespace語句。,以上介紹的是有名字的命名空間,C+還允許使用沒有名字的命名空間,如在文件A中聲明了以下的無名命名空間: namespace/命名空間沒有名字 void fun() /定義命名空間成員 coutOK.endl; 由于命名空間沒有名字,在其他文件中顯然無法引用,它只在本文件的作用域內(nèi)有效。無名命名空間的成員fun函數(shù)的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 溝通與協(xié)調(diào)打造和諧職場環(huán)境
- 生態(tài)建筑引領(lǐng)未來商業(yè)趨勢
- 現(xiàn)代科技在股票市場分析中的應(yīng)用
- 校園餐飲消費大數(shù)據(jù)洞察學生消費習慣
- 2024年八年級生物下冊 6.2.1遺傳說課稿 (新版)冀教版
- 2024年八年級物理下冊 8.1認識壓強說課稿 (新版)粵教滬版
- 14《普羅米修斯》(說課稿)2024-2025學年-統(tǒng)編版語文四年級上冊
- 2024年五年級數(shù)學下冊 五 分數(shù)除法練習五說課稿 北師大版
- 2024-2025學年高中歷史 專題1 中國傳統(tǒng)文化主流思想的演變 3 宋明理學說課稿 人民版必修3
- 2024-2025學年八年級物理下冊 第十章 從粒子到宇宙 10.1 認識分子說課稿 (新版)粵教滬版
- 冀教版小學英語六年級下冊全冊教案
- 2024人工智能開源大模型生態(tài)體系研究報告
- 2024年中考語文復習分類必刷:非連續(xù)性文本閱讀(含答案解析)
- 緊密型縣域醫(yī)療衛(wèi)生共同體慢病管理中心運行指南試行等15個指南
- YYT 0681.11-2014 無菌醫(yī)療器械包裝試驗方法 第11部分:目力檢測醫(yī)用包裝密封完整性
- 遼寧省沈陽市第七中學2023-2024學年七年級下學期期末數(shù)學試題
- 2024年湖南工業(yè)職業(yè)技術(shù)學院單招職業(yè)技能測試題庫附答案
- 快速入門穿越機-讓你迅速懂穿越機
- 水利安全生產(chǎn)風險防控“六項機制”右江模式經(jīng)驗分享
- 2024年四川省成都市高新區(qū)中考數(shù)學二診試卷
- 幼兒園衛(wèi)生保健開學培訓
評論
0/150
提交評論