版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、C語言程序設(shè)計,第8章 面向?qū)ο蠹夹g(shù)與C++,8.1 C++的起源和特點(diǎn) 8.2 簡單的C++程序 8.3 C++程序的上機(jī)實(shí)現(xiàn) 8.4 C++的輸入和輸出 8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值 8.6 內(nèi)聯(lián)函數(shù) 8.7 重載函數(shù) 8.8 變量的引用 8.9 面向?qū)ο蟮母拍詈退枷?8.10 類和對象 8.11 構(gòu)造函數(shù) 8.12 析構(gòu)函數(shù) 8.13 繼承與派生類,8.1 C++的起源和特點(diǎn),早期的程序
2、是用機(jī)器語言或者匯編語言編寫最早的高級語言是20世紀(jì)50年代中期出現(xiàn)的ForTRAN 50年代后期的Algol語言提出了塊結(jié)構(gòu)的思想60年代的Simula 67語言首次提出了對象的概念70年代的Ada語言是一種基于對象的語言,支持?jǐn)?shù)據(jù)抽象類型,隨后面出現(xiàn)的Smalltalk語言豐富了面向?qū)ο蟮母拍?,是最具有影響的面向?qū)ο蟮恼Z言之一1972年在DEC PDP-11計算機(jī)上實(shí)現(xiàn)了最初的C語言1980年AT&T貝爾實(shí)驗(yàn)室研
3、制成功“帶類的C語言” 1983年正式取名為C++1994年制定了ANSI C++標(biāo)準(zhǔn),8.1 C++的起源和特點(diǎn),C++是一種高效實(shí)用的面向?qū)ο蟪绦蛟O(shè)計(Object Oriented Programming,簡稱OOP)語言。 C++從C進(jìn)化而來,是C語言的超集,它除了保持C的簡捷和高效外,還克服了C的不足,全面引進(jìn)了面向?qū)ο蟮募夹g(shù)。 隨著C++逐漸成為ANSI標(biāo)準(zhǔn),這種新的面向?qū)ο蟮某绦蛟O(shè)計語言迅速成
4、為深受編程人員喜歡的一種高級程序設(shè)計語言,幾乎所有計算機(jī)研究和應(yīng)用領(lǐng)域都能看到C++的影子。,8.2 簡單的C++程序,例8.1 在屏幕上顯示一句話This is a C++ program,例題中的cout稱作標(biāo)準(zhǔn)輸出流,它代表標(biāo)準(zhǔn)輸出設(shè)備(一般指屏幕),在頭文件iostream.h中有定義?!?lt;<’是一個運(yùn)算符,它把cout右邊的字符串送往屏幕顯示,輸出語句最后的符號endl表示換行。,8.2 簡單的C++程序,例8.2
5、 從鍵盤上輸入兩個實(shí)數(shù),求它們的和,程序中的cin稱作標(biāo)準(zhǔn)輸入流,運(yùn)算符’>>’的作用是把從鍵盤輸入的數(shù)據(jù)送到它右邊的變量表中保存起來。語句 cin>>x>>y; 表示鍵入兩個實(shí)數(shù),分別賦給變量x和y,相當(dāng)于C語言中的輸入命令scanf(“%d %d”, &x, &y);,8.2 簡單的C++程序,例8.3 上例8.2還可以用自定義函數(shù)的方法來實(shí)現(xiàn),8.2 簡單的C++程序,C++程
6、序的一些簡單特點(diǎn)完整的C++源程序文件由一個或多個文件組成,每個文件可以包含若干個函數(shù)。在完整的C++程序中,可能會出現(xiàn)許多函數(shù),但程序中有且僅有一個主函數(shù)main(),程序的執(zhí)行總是從主函數(shù)main()開始執(zhí)行的,至于其它函數(shù)則是通過函數(shù)的嵌套調(diào)用來進(jìn)行;2.在C++中實(shí)現(xiàn)注釋有兩種方法,一種方法是可以沿用C語言中的’/*’和’*/’進(jìn)行注釋,它一般適用于有多行注釋信息的情況;另一種是使用符號//進(jìn)行注釋,//之后本行的所有字符都
7、是注釋內(nèi)容。如果注釋信息只有一行文字,通常使用//注釋;3.輸入/輸出時C++程序經(jīng)常使用的頭文件iostream.h頭文件,因?yàn)樵谶@個頭文件中定義了標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出操作,而C中經(jīng)常用到stdio.h這個頭文件;4.C++中主函數(shù)main()函數(shù)體也是用一對花括號’{‘和’}’括起來,體內(nèi)每條語句仍然以分號結(jié)束。如果主函數(shù)main()沒有明確的返回值,在C++中main()的返回值類型就應(yīng)該定義為void類型,而在C中main()
8、的返回值類型可以是void型的,但更多情況下默認(rèn)不寫(其實(shí)是int型的)。,8.3 C++程序的上機(jī)實(shí)現(xiàn),完整的C++上機(jī)過程包括編輯、編譯和連接、運(yùn)行這三個環(huán)節(jié) 若是在MS-DOS方式下,可以使用Turbo C++或者Borland C++如果是在Windows 9x/2000/XP/2003平臺下,可以使用Microsoft Visual C++,8.4 C++的輸入和輸出,對于輸入/輸出, C++除了保留C語言中的scanf(
9、)和printf()這兩個函數(shù)外,還增加了標(biāo)準(zhǔn)輸入流cin和標(biāo)準(zhǔn)輸出流cout,后者這兩個標(biāo)準(zhǔn)流在iostream.h頭文件中有定義,8.4.1 用cout輸出 8.4.2 用cin輸入,8.4.1 用cout輸出,在C++中,用cout和插入運(yùn)算符<<可以輸出任何類型的數(shù)據(jù) 例:cout<<”abcdefg\n”; 將字符串”abcdefg\n”插入到輸出流cout中去,實(shí)際上就是在屏幕上顯示字符
10、串a(chǎn)bcdefg,與C中的語句 printf(“%s\n”, “abcdefg”); 作用相同;或者寫成以下的形式: cout<<”abcdefg”<<endl; 其中endl這個控制符表示輸出換行,8.4.1 用cout輸出,當(dāng)程序中需要輸出多個表達(dá)式的結(jié)果時,cout后面可以跟上多個<<運(yùn)算符,通過<<把這些表達(dá)式按從左到右的順序逐個連接起來。
11、例如:cout<<”3+2=”<<3+2<<”, ”<<”3.1*2.2=”<<3.1*2.2<<endl;輸出結(jié)果為 3+2=5, 3.1*2.2=6.82 在C++中用cout輸出數(shù)據(jù)時,可以不用指定輸出表達(dá)式的具體格式,程序執(zhí)行時系統(tǒng)會按照輸出項(xiàng)的數(shù)據(jù)類型自動進(jìn)行輸出,這樣就比用printf( )函數(shù)來得方便,故cout的輸出形式
12、經(jīng)常使用,8.4.2 用cin輸入,C++中的標(biāo)準(zhǔn)輸入流cin與提取運(yùn)算符>>配合使用共同完成數(shù)據(jù)的鍵盤輸入,使用時可以不用指定數(shù)據(jù)類型。 float x; int n; cin>>x>>n; 作用:從鍵盤上分別輸入一個實(shí)數(shù)和一個整數(shù),然后把實(shí)數(shù)賦給變量x,把整數(shù)賦給變量n。 鍵入時注意兩個數(shù)之間要用空格分隔,輸入格式如下: 3.2 5↙ 上
13、述的輸入語句相當(dāng)于C中的: scanf(“%f%d”, &x, &n);,8.4.2 用cin輸入,例8.4 用cin和cout實(shí)現(xiàn)的輸入和輸出舉例,8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值,在進(jìn)行函數(shù)定義(或函數(shù)說明)時,C++允許給一個或多個形參指定默認(rèn)值(亦稱缺省值),使得函數(shù)調(diào)用更加方便,程序設(shè)計更加靈活。 下面來看一個使用了參數(shù)默認(rèn)值的示例 int add3int(int a, int b=5,
14、int c=8); 這是對用戶自定義函數(shù)add3int( )進(jìn)行說明的語句,本例中使用了三個形參a、b和c。 在函數(shù)說明時對后兩個參數(shù)b和c分別設(shè)置了默認(rèn)值,其中參數(shù)b的默認(rèn)值為5,參數(shù)c的默認(rèn)值為8。,8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值,在設(shè)置函數(shù)默認(rèn)值時應(yīng)注意: 應(yīng)該從函數(shù)形參表中最右邊的那個參數(shù)開始設(shè)置默認(rèn)值,指定順序應(yīng)從右向左。在已指定了默認(rèn)值的參數(shù)的右邊不允許再出現(xiàn)尚未指定默認(rèn)值的參數(shù)。因此在設(shè)置函數(shù)默
15、認(rèn)值時,既可以為形參表中的所有參數(shù)指定默認(rèn)值,也可以為形參表中最右邊的幾個連續(xù)參數(shù)指定默認(rèn)值 當(dāng)函數(shù)被調(diào)用時,如果指定了具體的實(shí)參表,則調(diào)用時的實(shí)參值將取代原來參數(shù)的默認(rèn)值;如果沒有給定實(shí)參值,將沿用參數(shù)原來的默認(rèn)值,8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值,在設(shè)置函數(shù)默認(rèn)值時應(yīng)注意: 指定函數(shù)參數(shù)默認(rèn)值的這種語法現(xiàn)象在程序設(shè)計時可有可無。當(dāng)需要對函數(shù)參數(shù)設(shè)置默認(rèn)值時,假如該函數(shù)還有函數(shù)聲明時,則默認(rèn)的參數(shù)值就應(yīng)該設(shè)置在函數(shù)聲明部分
16、而不能設(shè)置在函數(shù)的定義部分;如果程序中沒有函數(shù)聲明,默認(rèn)的參數(shù)值將設(shè)置在函數(shù)定義部分 在給函數(shù)參數(shù)設(shè)置默認(rèn)值時,被指定的默認(rèn)值不僅可以是常數(shù),也可以是表達(dá)式。全局變量可以被指定為參數(shù)的默認(rèn)值,但局部變量不行,因?yàn)槟J(rèn)參數(shù)的函數(shù)調(diào)用是在編譯時確定的,而局部變量在編譯時無法確定,8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值,例8.5 分析下面程序的輸出結(jié)果,要求熟悉默認(rèn)參數(shù)的用法,第一次調(diào)用:由于沒有指定實(shí)參表,三個參數(shù)都采用原來的默認(rèn)值(1、2、3
17、); 第二次調(diào)用:只有一個實(shí)參,指定了第一個參數(shù)的實(shí)參值,其余兩個參數(shù)沿用默認(rèn)值,此時的實(shí)參值為(4、2、3); 第三次調(diào)用:指定了兩個實(shí)參,指定了前兩個參數(shù)的實(shí)參值,第三個參數(shù)沿用默認(rèn)值,此時的實(shí)參值為(4、5、3); 第四次調(diào)用:指定了三個實(shí)參,表示三個參數(shù)全部都用新的實(shí)參值(4、5、6),原來設(shè)置的參數(shù)默認(rèn)值無效。,8.5 設(shè)置函數(shù)參數(shù)的默認(rèn)值,例8.6 分析程序的運(yùn)行結(jié)果,了解全局變量充當(dāng)參數(shù)的默認(rèn)值,8.6 內(nèi)聯(lián)函數(shù),在
18、設(shè)計程序時,合理地使用函數(shù),能做到“一次定義,多次使用” ,實(shí)現(xiàn)了程序代碼和數(shù)據(jù)的共享,減少了程序的目標(biāo)代碼。 但是,調(diào)用函數(shù)時卻要花費(fèi)一定的時間和內(nèi)存空間來保存調(diào)用的現(xiàn)場,程序效率有所降低,特別是對于那些需要頻繁調(diào)用、但本身代碼并不大的函數(shù),效率尤為不高。 為了解決這個問題,C++引入了內(nèi)聯(lián)函數(shù)。當(dāng)一個使用了內(nèi)聯(lián)函數(shù)的源程序被編譯時,編譯系統(tǒng)會把程序中出現(xiàn)的調(diào)用內(nèi)聯(lián)函數(shù)的語句,直接用內(nèi)聯(lián)函數(shù)的函數(shù)體來替換,這樣處理雖然
19、增加了最終的目標(biāo)代碼,但卻節(jié)省了調(diào)用過程中的時間和空間的開銷,另外由于內(nèi)聯(lián)函數(shù)的代碼往往比較小,這樣做對程序執(zhí)行的影響也較小,效率較高。 對于代碼小而且訪問頻繁的函數(shù),適宜使用內(nèi)聯(lián)函數(shù)。,8.6 內(nèi)聯(lián)函數(shù),內(nèi)聯(lián)函數(shù)的定義方法 在定義函數(shù)時,要求在函數(shù)首部的最左邊,也就是函數(shù)返回值的類型名前面,加上內(nèi)聯(lián)函數(shù)的關(guān)鍵字inline,其余部分與傳統(tǒng)的函數(shù)定義相同。例:定義一個用于計算兩個數(shù)之和的內(nèi)聯(lián)函數(shù)
20、inline int sum2int(int m, int n){ return m+n;},8.6 內(nèi)聯(lián)函數(shù),例8.7 計算自然數(shù)1到10中各個數(shù)的立方值,8.6 內(nèi)聯(lián)函數(shù),使用內(nèi)聯(lián)函數(shù)的注意要點(diǎn) 內(nèi)聯(lián)函數(shù)內(nèi)不允許出現(xiàn)循環(huán)語句和開關(guān)語句,如果一個內(nèi)聯(lián)函數(shù)包含了這些語句,則按普通函數(shù)處理 內(nèi)聯(lián)函數(shù)的函數(shù)體一般不宜過大,以1至5行為宜 在以后的講述中我們還會學(xué)到類,在類體內(nèi)定義的成員函數(shù)都是內(nèi)聯(lián)函數(shù),8.7 重載函數(shù)
21、,重載函數(shù)的定義 重載函數(shù)是指同一個函數(shù)名稱對應(yīng)著多個不同的函數(shù)實(shí)現(xiàn)例:定義重載函數(shù)abs(),用來計算3個不同類型數(shù)據(jù)的絕對值 int abs(int); long abs(long); double abs(double); 重載函數(shù)在功能上比較接近,在定義時要有所區(qū)別。各重載函數(shù)之間的差別主要表現(xiàn)在:函數(shù)返回值的類型、函數(shù)參數(shù)的類型、函數(shù)參數(shù)的個數(shù)、函數(shù)參數(shù)的順序等方面的不同,系統(tǒng)
22、會根據(jù)這些不同來選擇相應(yīng)的函數(shù)。 僅僅靠函數(shù)返回值類型的不同來定義重載函數(shù)是不行的,因此在使用重載函數(shù)時,在函數(shù)名字相同的前提下要將上述的那些區(qū)別明顯地表現(xiàn)出來。,8.7 重載函數(shù),使用重載函數(shù)時編譯系統(tǒng)會根據(jù)如下原則進(jìn)行選擇重載函數(shù)至少要在參數(shù)類型、參數(shù)個數(shù)、參數(shù)順序上要有所不同,僅僅在函數(shù)返回值類型上的不同是不夠的例:在下面的三個函數(shù)聲明中 int myfun(int, double);/*
23、第一個函數(shù) */ int myfun(double, int);/* 第二個函數(shù) */ void myfun(int,double); /* 第三個函數(shù) */ 第一個函數(shù)和第二個函數(shù)可以重載,因?yàn)槎咴趨?shù)順序上不同;第二個函數(shù)和第三個函數(shù)也可以重載,因?yàn)樗鼈兊膮?shù)順序和返回值類型都不同。但第一個函數(shù)和第三個函數(shù)的形參表相同,僅僅在返回值類型上不同,因此它們是不能重載的。,8.7 重載函數(shù),使
24、用重載函數(shù)時編譯系統(tǒng)會根據(jù)如下原則進(jìn)行選擇在使用重載函數(shù)時,需要逐一比較實(shí)參的類型與被調(diào)用的重載函數(shù)中的形參類型,從而決定調(diào)用哪個重載函數(shù)判斷過程如下:查找是否存在一個嚴(yán)格匹配的重載函數(shù),如果找到了就調(diào)用那個函數(shù),否則將進(jìn)入第2步;通過內(nèi)部數(shù)據(jù)轉(zhuǎn)換查找一個匹配的,如果找到了就調(diào)用那個函數(shù),否則進(jìn)入第3步;通過用戶所定義的強(qiáng)制類型轉(zhuǎn)換來查找一個匹配的,如果找到了就調(diào)用那個函數(shù),否則提示函數(shù)調(diào)用時出錯。,8.7 重載函數(shù),例:假
25、設(shè)重載函數(shù)fun( )有如下兩種形式: void myfun(int); void myfun(double);對于下列條件的函數(shù)調(diào)用,函數(shù)fun()的匹配情況如下:myfun(1); // 匹配void myfun(int),為嚴(yán)格匹配myfun(1.5); // 匹配void myfun(double),為嚴(yán)格匹配myfun(‘m’); // 匹配void myfun(
26、int),這是內(nèi)部數(shù)據(jù)轉(zhuǎn)換后的匹配myfun((double)5);// 匹配void myfun(double),這是強(qiáng)制類型的匹配使用重載函數(shù)時的注意事項(xiàng) 不能用類型定義語句(typedef)定義的類型名來區(qū)分重載函數(shù)的參數(shù)類型在定義重載函數(shù)時,應(yīng)注意同名函數(shù)應(yīng)該具有相同的功能,如果讓重載函數(shù)去執(zhí)行不同的功能,這是不好的編程風(fēng)格,例8.8 下列程序中定義了求幾個整數(shù)最大值的重載函數(shù),閱讀程序?qū)懗鲞\(yùn)行結(jié)果,8.8 變量的
27、引用,8.8.1 引用的概念8.8.2 引用作函數(shù)參數(shù),8.8.1 引用的概念,引用(reference)的定義 :簡單地說,引用就是某個變量(或?qū)ο螅┑膭e名 建立引用的格式: 類型名 &引用名 = 變量名或?qū)ο竺?例:int a; int &ra=a;,在上面這個例子中,&是引用說明符而不是地址運(yùn)算符;符號&放在ra前,表示ra是對變量a的一個引用,在建立引用時對ra進(jìn)行
28、了初始化,這樣ra和a便“捆綁”在一起了。,8.8.1 引用的概念,在為某個變量建立引用時,要求對引用進(jìn)行初始化。此時變量和它的引用便“捆綁”在一起了,程序中對引用的改變也就是對變量的改變 使用引用時要注意,引用本身不是值,它不占用內(nèi)存空間,對引用只能說明而不能定義,引用僅僅是替代某個變量(或?qū)ο螅┑膭e名而已 下述四種定義引用說明符的書寫形式都是一樣的: int&ra=a; int& ra=a;
29、int &ra=a; int & ra=a;(注意這四種書寫格式中空格的位置),8.8.1 引用的概念,例8.9 閱讀程序?qū)懗鲞\(yùn)行結(jié)果,8.8.1 引用的概念,引用是C++中的概念,C中沒有這一概念,引用與指針不同,不能把二者混淆起來 指針是變量,有獨(dú)立的內(nèi)存單元,而引用不是變量,引用和與它捆綁在一起的變量(或?qū)ο螅┱加猛粌?nèi)存單元;指針可以被引用,而引用不能再次被引用;指針可以作為數(shù)組元素,而引用不
30、能作為數(shù)組元素。指針作為數(shù)組元素時該數(shù)組稱為指針數(shù)組;可以有空的指針,但不能有空引用,8.8.2 引用作函數(shù)參數(shù),在定義函數(shù)時形參可以是引用引用充當(dāng)函數(shù)參數(shù)時傳遞的是地址,與指針變量作函數(shù)參數(shù)所起的作用相同一般地,引用作函數(shù)參數(shù)時程序的可讀性要好些,這是因?yàn)楫?dāng)引用作函數(shù)形參時,調(diào)用函數(shù)時的實(shí)參可以用變量名(或者表達(dá)式),這與傳統(tǒng)意義上的傳值調(diào)用相似。與之相反,如果是指針變量用作函數(shù)參數(shù),則函數(shù)調(diào)用時實(shí)參必須是地址,8.8.2 引用
31、作函數(shù)參數(shù),例8.10 定義一個函數(shù)swap( )來交換兩個int變量的值,要求用指針變量作函數(shù)參數(shù),8.8.2 引用作函數(shù)參數(shù),例8.11 定義一個函數(shù)swap( )來交換兩個int變量的值,要求用引用作函數(shù)參數(shù),8.9 面向?qū)ο蟮母拍詈退枷?8.9.1 面向?qū)ο蟮母拍?.9.2 面向?qū)ο蠓椒ㄅc結(jié)構(gòu)化方法的比較8.9.3 面向?qū)ο笙到y(tǒng)的特性,8.9.1 面向?qū)ο蟮母拍?一、對象的概念:對象有兩方面的含義,即在客觀世界中的含義
32、和在程序世界中的含義客觀世界中的任何一個事物都可以看成對象在程序世界中,對象是問題空間中的個體或事物的抽象表示,是其屬性和相關(guān)操作的結(jié)合體。屬性表示了對象的性質(zhì),屬性值刻劃了對象的所有可能的狀態(tài);與屬性相關(guān)的操作表示了對象的行為,施加給對象的操作會引起對象狀態(tài)的變化對象是面向?qū)ο笙到y(tǒng)中最基本的概念,是問題空間中對客觀事物的一種抽象表示,也是應(yīng)用系統(tǒng)的基本組成單位,8.9.1 面向?qū)ο蟮母拍?二、類的概念:在面向?qū)ο笙到y(tǒng)中,類是一
33、種抽象機(jī)制,它是對一組具有共同屬性和行為的對象的一般描述類與對象的關(guān)系是一個抽象與具體的關(guān)系。類是把從具體的對象中抽取出來的共同屬性所形成的一般化定義,是對象的抽象,而對象則是類的一個實(shí)例,8.9.1 面向?qū)ο蟮母拍?三、繼承的概念:繼承是一個對象可以獲取另一個對象特性的機(jī)制類和類之間的繼承關(guān)系,是客觀世界中遺傳關(guān)系的直接模擬,它表示了類與類之間的內(nèi)在聯(lián)系 類有父類和子類之分,父類也叫基類,子類又叫派生類。子類除了可以沿用父類的
34、某些特征外,它還具有本身獨(dú)特的屬性和操作正是因?yàn)橛辛死^承,低層的類只需定義特定于它的特征,就可以共享高層的類特征了,8.9.1 面向?qū)ο蟮母拍?四、消息的概念:消息是向?qū)ο蟀l(fā)出的服務(wù)請求。消息的發(fā)送方是一個要求提供服務(wù)的對象,而消息的接收方是一個能夠提供服務(wù)的對象在面向?qū)ο蟮南到y(tǒng)中,各對象之間是相互獨(dú)立的,對象之間通過消息進(jìn)行聯(lián)系,8.9.1 面向?qū)ο蟮母拍?面向?qū)ο蟪绦蛟O(shè)計(Object Oriented Programming
35、,簡稱OOP) 從問題空間中客觀存在的事物出發(fā)構(gòu)造軟件系統(tǒng),用對象這個封裝的單元來表示問題空間中的客觀實(shí)體,用消息傳遞來建立對象之間的聯(lián)系,把相同屬性和相同行為的對象歸為一類,通過在不同層次上運(yùn)用抽象的原則,就可以得到較一般的類和較特殊的類,8.9.2 面向?qū)ο蠓椒ㄅc結(jié)構(gòu)化方法的比較,在問題抽象階段。結(jié)構(gòu)化方法以算法為核心,按照數(shù)據(jù)變換的過程進(jìn)行分解,重點(diǎn)是描述數(shù)據(jù)變換的功能模塊。面向?qū)ο蠓椒ㄊ且詳?shù)據(jù)為核心,強(qiáng)調(diào)問題空間中的對象
36、模型在設(shè)計階段。結(jié)構(gòu)化方法采用自頂向下、逐步求精的指導(dǎo)思想,采用模塊化編程,各個模塊有可能保持較強(qiáng)的獨(dú)立性,但往往獨(dú)立于數(shù)據(jù)結(jié)構(gòu)。面向?qū)ο蠓椒ㄊ菑膶ο蟪霭l(fā),將對象的數(shù)據(jù)結(jié)構(gòu)和相應(yīng)的操作代碼集中在一個封裝的實(shí)體內(nèi),對象和對象之間通過消息進(jìn)行聯(lián)系結(jié)構(gòu)化方法的程序模型=算法+數(shù)據(jù)結(jié)構(gòu)面向?qū)ο蠓椒ǖ某绦蚰P?對象+消息,8.9.3 面向?qū)ο笙到y(tǒng)的特性,面向?qū)ο笙到y(tǒng)的三個特征:封裝性、繼承性和多態(tài)性封裝性(encapsulation)
37、 在程序設(shè)計中,封裝性指的是把數(shù)據(jù)以及對數(shù)據(jù)的操作集中在一起所構(gòu)成的一個實(shí)體。用戶不必知道對象行為的實(shí)現(xiàn)細(xì)節(jié),只需要根據(jù)對象提供的外部接口來訪問對象。因此從用戶的角度看,這些對象的行為就象包含在一個“黑匣子”里,是隱蔽的和不可見的。 封裝性是一種信息隱藏技術(shù),系統(tǒng)設(shè)計員會清楚地標(biāo)明提供的服務(wù)接口,服務(wù)的具體實(shí)現(xiàn)卻被屏蔽封裝著,用戶和應(yīng)用程序員只能使用對象提供的操作功能而不清楚內(nèi)部數(shù)據(jù)或操作代碼的實(shí)現(xiàn)細(xì)節(jié)。
38、 采用對象封裝機(jī)制的目的在于將對象的使用者和設(shè)計者分開。,8.9.3 面向?qū)ο笙到y(tǒng)的特性,繼承性(inheritance) 繼承所表達(dá)的是類與類之間的相互關(guān)系,使得某類對象可以繼承另一類對象的特征和功能,實(shí)現(xiàn)了信息共享和代碼重用,減少了冗余。 在繼承層次結(jié)構(gòu)中,父類稱為基類,子類稱為派生類。具體地說,如果類B繼承了類A,則類B中的對象就具有了類A對象的一切特征(指數(shù)據(jù)屬性)和功能(指操作),我們就稱類A為基
39、類(或父類),稱類B為類A的派生類(或子類)。 繼承機(jī)制帶來的最大優(yōu)勢在于軟件系統(tǒng)易于擴(kuò)充,降低了軟件開發(fā)的費(fèi)用和復(fù)雜性,因此面向?qū)ο蠓椒ǚ浅_m合于開發(fā)大型軟件系統(tǒng)。,8.9.3 面向?qū)ο笙到y(tǒng)的特性,多態(tài)性(polymorphism) 多態(tài)性描述的是同一個消息可以根據(jù)發(fā)送消息對象的不同而采取不同的行為方式。C++支持的多態(tài)性有兩種,即編譯時的多態(tài)和運(yùn)行時的多態(tài)。 編譯時的多態(tài)是通過重載來實(shí)現(xiàn)的,到底
40、執(zhí)行哪個重載版本在編譯時就可以知道,所以是相對靜態(tài)的多態(tài);運(yùn)行時的多態(tài)是通過虛函數(shù)來實(shí)現(xiàn)的,到底運(yùn)行哪個函數(shù)版本需要在運(yùn)行時找出發(fā)送消息的對象來確定,編譯器在編譯時采用動態(tài)聯(lián)編的手段。,8.10 類和對象,8.10.1 類的定義8.10.2 對象的定義8.10.3 對象的成員表示,8.10.1 類的定義,類的定義格式分為兩大部分,即說明部分和實(shí)現(xiàn)部分。說明部分用來說明該類中的多個成員(包括被說明的數(shù)據(jù)成員和成員函數(shù)),而實(shí)現(xiàn)
41、部分用來描述說明部分中成員函數(shù)的實(shí)現(xiàn)(或定義)。 一般地,類的說明部分放在類體內(nèi),告訴使用者“做什么”,而類的實(shí)現(xiàn)部分放在類體外,告訴使用者“怎么做”。當(dāng)然也有些簡單的類將說明部分和實(shí)現(xiàn)部分合并在一起,都放在類體內(nèi)。,8.10.1 類的定義,類的一般定義格式: class 類名 // 說明部分 { public: 公有的數(shù)據(jù)和成員函數(shù) private: 私有的數(shù)據(jù)和成員函數(shù)
42、 }; // 實(shí)現(xiàn)部分 各成員函數(shù)的實(shí)現(xiàn) ……,8.10.1 類的定義,定義一個類時要注意以下幾點(diǎn):class是定義類的關(guān)鍵字,習(xí)慣上用字母T開頭的標(biāo)識符表示類名,以區(qū)別對象名和函數(shù)名。類體中包含的數(shù)據(jù)成員和成員函數(shù)的說明或定義,用一對花括號{和}括起來從訪問權(quán)限上看,類的成員分為三大類 公有的(public) 私有的(private) 受保護(hù)的(protected)成
43、員函數(shù)必須在類體內(nèi)給出原型說明,位置在類體內(nèi)或者類體外。放在類體內(nèi)的函數(shù)被默認(rèn)為是內(nèi)聯(lián)函數(shù),而放在類體外定義的函數(shù)是一般函數(shù)。如果要定義內(nèi)聯(lián)函數(shù),只需在函數(shù)首部的最前面加上關(guān)鍵字inline,8.10.1 類的定義,在類體外定義成員函數(shù)時的格式: :: (){ }其中作用域運(yùn)算符::是用來標(biāo)識某個成員函數(shù)是屬于哪個類的。,8.10.1 類的定義,例8.12 給出一個關(guān)于日期類的定義。 類TDate的體內(nèi)一共說明了6
44、個成員,其中3個成員函數(shù)是公有的(public),3個數(shù)據(jù)成員是私有的(private) 。 為了敘述方便,我們把類TDate的定義內(nèi)容全部寫入一個名叫tdate.h的頭文件中,8.10.1 類的定義,例8.13 定義類的時候,成員函數(shù)的定義部分除了可以寫類體外(如例8.12所示),也可以寫在類體內(nèi)。,8.10.2 對象的定義,對象的定義格式如下 類名 對象名表;類名是待定義的對象所屬的類的名
45、字,這個類要求事先已經(jīng)定義好了在定義對象時,直接用類名就可以了,無需在類名前再加上關(guān)鍵字class對象名表中可以是一個或多個對象名,多個對象名之間用逗號分隔,可以是一般簡單的對象名、指向?qū)ο蟮闹羔樏蛞妹?,或者是對象?shù)組名例:為前面已經(jīng)有所定義了的類TDate定義了幾個對象TDate date1, date2, *pdate, &rdate1=date1, date[31];,8.10.3 對象的成員表示,一般
46、對象的成員表示如下: 對象名 . 數(shù)據(jù)成員名 對象名 . 成員函數(shù)名(參數(shù)表)指向?qū)ο蟮闹羔樀某蓡T表示如下: 對象指針名 -> 數(shù)據(jù)成員名 對象指針名 -> 成員函數(shù)名(參數(shù)表)或者 (*對象指針名) . 數(shù)據(jù)成員名 (*對象指針名) . 成員函數(shù)名(參數(shù)表),8.10.3 對象的成員表示,例8.14 分析程序的運(yùn)行結(jié)果,類TDate定義在頭文件tdate.h之中(見例8.12)。程序中定義了
47、兩個對象d1和d2,通過成員函數(shù)SetDate() 分別給兩個對象的各數(shù)據(jù)成員賦值,調(diào)用成員函數(shù)IsLeapYear()判斷d1和d2對應(yīng)的年是否為閏年,通過調(diào)用成員函數(shù)Print()在屏幕顯示d1和d2的私有數(shù)據(jù)成員年、月、日的值。,8.11 構(gòu)造函數(shù),構(gòu)造函數(shù)(constructor)是一種特殊的成員函數(shù)與類中的其它成員函數(shù)不一樣,構(gòu)造函數(shù)不需要用戶調(diào)用,它是在建立一個對象時由系統(tǒng)自動執(zhí)行,于是完成了對新建對象的初始化構(gòu)造函數(shù)
48、的名字與類名相同,它可以帶一個參數(shù)或者多個參數(shù),也可以沒有參數(shù)。在定義和說明構(gòu)造函數(shù)時,不必指明函數(shù)的類型,因?yàn)樗鼪]有返回值,更不需要加void類型說明構(gòu)造函數(shù)的說明部分一般放在類體中,至于函數(shù)定義部分,可以放在類體內(nèi),也可以放在類體外,例8.15 利用構(gòu)造函數(shù)完成對新創(chuàng)建的對象的初始化,例8.16 定義構(gòu)造函數(shù)給兩個不同的對象賦予不同的初值,例8.17 定義一個重載的構(gòu)造函數(shù),8.11 構(gòu)造函數(shù),默認(rèn)的構(gòu)造函數(shù)是無參數(shù)的空函數(shù),定義
49、格式如下 類名 :: 默認(rèn)構(gòu)造函數(shù)名( ) { }默認(rèn)構(gòu)造函數(shù)名與類同名,由于無參數(shù),因此默認(rèn)構(gòu)造函數(shù)不能重載當(dāng)定義一個沒有給定初始值的對象時,系統(tǒng)會自動調(diào)用默認(rèn)構(gòu)造函數(shù),對新創(chuàng)建的對象進(jìn)行初始化。當(dāng)該對象的存儲屬性是外部的(extern)或靜態(tài)的(static),它的所有數(shù)據(jù)成員將被初始化為0(或空)。如果對象是自動的(auto或省略存儲屬性),則在使用前必須對該對象賦初值,假設(shè)在沒有為對象賦
50、初值之前就已經(jīng)使用了數(shù)據(jù)成員,那將是無意義的,8.12 析構(gòu)函數(shù),析構(gòu)函數(shù)(destructor)與構(gòu)造函數(shù)(constructor)的作用相反。當(dāng)對象的生存期結(jié)束時,系統(tǒng)將自動調(diào)用析構(gòu)函數(shù)來釋放這個對象析構(gòu)函數(shù)也是一種特殊的成員函數(shù),其函數(shù)名也與類名相同,為了與構(gòu)造函數(shù)名區(qū)分開,特意在類名前加上符號~,以示析構(gòu)析構(gòu)函數(shù)沒有參數(shù),也不能指定函數(shù)返回值類型(包括void類型),因此析構(gòu)函數(shù)不能重載,而且在一個類中只能定義一個析構(gòu)函數(shù)
51、析構(gòu)函數(shù)的說明一般放在類體內(nèi),它的函數(shù)體可以寫在類體內(nèi),也可以寫在類體外,8.12 析構(gòu)函數(shù),在以下兩種情況下,析構(gòu)函數(shù)將由系統(tǒng)自動執(zhí)行:當(dāng)一個對象的生存期結(jié)束時,將自動調(diào)用析構(gòu)函數(shù)來釋放該對象使用new運(yùn)算符創(chuàng)建的對象,在使用delete運(yùn)算符釋放該對象時,系統(tǒng)將自動調(diào)用析構(gòu)函數(shù)如果類中沒有定義析構(gòu)函數(shù),系統(tǒng)將自動生成一個默認(rèn)的析構(gòu)函數(shù)。默認(rèn)析構(gòu)函數(shù)定義格式如下 類名 :: ~ 默認(rèn)析構(gòu)函數(shù)名( ) { }
52、 其中,默認(rèn)析構(gòu)函數(shù)名與類名相同,該析構(gòu)函數(shù)不進(jìn)行任何操作。,例8.18 分析下面程序的運(yùn)行結(jié)果,說明構(gòu)造函數(shù)和析構(gòu)函數(shù)是如何被調(diào)用的。,8.12 析構(gòu)函數(shù),8.13 繼承與派生類,8.13.1 繼承與派生類的概念8.13.2 派生類的定義格式8.13.3 公有派生類8.13.4 私有派生類8.13.5 保護(hù)成員,8.13.1 繼承與派生類的概念,繼承是C++的一個重要機(jī)制,它能自動地為一個類提供來自另一個類的數(shù)據(jù)
53、和操作,使得用戶可以在一個現(xiàn)有的類的基礎(chǔ)上,很快地建立起一個新的類,而不必從零開始重新設(shè)計,實(shí)現(xiàn)了代碼的共享和重用。,在左邊這個樹型結(jié)構(gòu)圖中,最高層是抽象的,以下每一層都是上一層的具體化,從圖中可以看出低層具有高層的特征。 例如:一旦選擇了丹頂鶴,就不用再說丹頂鶴有羽毛長翅膀了,因?yàn)檫@些特征丹頂鶴已經(jīng)從鳥類中繼承了。,8.13.1 繼承與派生類的概念,在面向?qū)ο蟮姆椒ㄖ校^承是針對類而言的。通過繼承的機(jī)制,能夠通過已有的類型來定義
54、新的類型。這樣,所定義的新類型在擁有原來類型屬性的同時,還擁有新的屬性,我們稱已存在的被用來生成新類型的類為基類,而從基類中派生出來的新類稱為派生類。 在C++中,派生類可以從一個基類(或多個基類)中派生得到。從一個基類中派生的繼承方式稱為單繼承,從多個基類中派生的繼承方式稱為多繼承。簡單地說,單繼承方式的派生類只有一個基類,而多繼承方式的派生類有多個基類。,8.13.1 繼承與派生類的概念,圖8.2所示的為單繼承,類B和
55、類C是兩個不同的派生類,但它們都是從類A中派生出來的。 圖8.3所示的是多繼承,類Z是由類X和類Y這兩個類派生出來的。,單繼承和多繼承舉例:,8.13.2 派生類的定義格式,單繼承派生類的定義格式 class 派生類名 : 繼承方式 基類名 { 派生類新增成員的定義 };其中:派生類是按指定的繼承方式從基類中派生出來的,具 體的繼承方式有以下三種:
56、public代表公有繼承方式private代表私有繼承方式protected代表保護(hù)繼承方式默認(rèn)的繼承方式為private,8.13.2 派生類的定義格式,多繼承派生類的定義格式 class 派生類名 : 繼承方式1 基類名1,繼承方式2 基類名2,……{ 派生類新增成員的定義};與單繼承派生類的定義相比較,多繼承派生類在定義格式上的基類名較多,這些基類名彼此之間用逗號分隔,而且每個基類名前都有一
57、個該基類的繼承方式說明默認(rèn)的繼承方式為私有繼承方式(private),8.13.2 派生類的定義格式,例8.19 定義一個學(xué)生類Tstudent,其數(shù)據(jù)成員包括學(xué)號、姓名和性別,對它進(jìn)行的操作是顯示每個學(xué)生的基本情況,若想在這個類的基礎(chǔ)上再添加年齡和年級信息。由于涉及到類中成員的修改,我們當(dāng)然可以拋開原來的類不管而重新定義一個新的類,但是利用類的繼承方法實(shí)現(xiàn)起來更方便。 在原有類Tstudent的基礎(chǔ)上派生出一個新類TnewSt
58、udent。請看下面的例8.20,8.13.2 派生類的定義格式,例8.20 定義一個派生類(在例8.19的基礎(chǔ)上),本例中Tstudent為基類(在例8.19中定義),TnewStudent是基類Tstudent的派生類,使用的繼承方式為public 派生類的成員函數(shù)NewList( )調(diào)用了基類的公有成員函數(shù)List( )來顯示學(xué)生的學(xué)號、姓名和性別,8.13.2 派生類的定義格式,派生類中的成員包括原來基類中的成員和自己
59、新增的成員對于派生類中新增的成員,如果在派生類定義中被定義為private,它們只能通過同一類的成員函數(shù)進(jìn)行訪問;如果被定義為public,則可以被外界所使用對于那些從基類中繼承過來的數(shù)據(jù)成員,并不是簡單地把基類中的private和public成員直接作為派生類的私有成員和公有成員,而要根據(jù)基類成員的訪問權(quán)限和派生類定義中的繼承方式共同決定(見表8.1),8.13.3 公有派生類,在定義一個派生類時,如果將基類的繼承方式指定為pub
60、lic,則該派生類稱為基類的公有派生類。例8.20定義的派生類TnewStudent就是公有派生類在公有派生類中,基類的public成員和protected成員仍然成為派生類中的public成員和protected成員,而基類中的private成員將不能被派生類訪問,只有通過基類中的成員函數(shù)才能引用它,8.13.4 私有派生類,在定義一個派生類時,如果將基類的繼承方式指定為private,則該派生類稱為基類的私有派生類在使用私有派生
61、類時,基類的public成員和protected成員都將成為派生類中的private成員,在派生類的成員函數(shù)中不能訪問基類的private成員,但可以訪問基類的公有成員,8.13.5 保護(hù)成員,控制符protected和public、private一樣,都是用來定義類中成員訪問權(quán)限的,其中用protected說明的成員稱為保護(hù)成員。和私有成員相類似,保護(hù)成員也不能被外界使用,但它能被派生類中的成員函數(shù)使用無論是私有派生類還是公有派生類
62、,基類的私有成員被繼承后都將變?yōu)椤安豢稍L問的成員”,如果想在派生類中使用基類的成員,可以將基類的成員定義為protected,例8.21 派生類中如何使用保護(hù)成員,8.13.6 派生類的構(gòu)造函數(shù),派生類中構(gòu)造函數(shù)的定義格式:派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名(參數(shù)表)派生類構(gòu)造函數(shù)的執(zhí)行過程在初始化基類中的數(shù)據(jù)成員時,首先調(diào)用基類的構(gòu)造函數(shù)產(chǎn)生一個無名的對象,把該對象的值存放到派生類的新建對象中,把它作為派生類對象成員
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 譚浩強(qiáng)c語言程序設(shè)計教程學(xué)習(xí)筆記第8章
- 譚浩強(qiáng)c語言程序設(shè)計教程學(xué)習(xí)筆記第8章
- c語言程序設(shè)計第6章課件-
- 第02章c語言程序設(shè)計基礎(chǔ)
- c語言程序設(shè)計ppt課件_第2章_簡單程序設(shè)計-
- c語言程序設(shè)計ppt-第2版-第7章-指針程序設(shè)計
- c語言程序設(shè)計與項(xiàng)目實(shí)踐第14章
- c語言程序設(shè)計_2 第10章 編譯預(yù)處理
- c語言程序設(shè)計 實(shí)驗(yàn)教學(xué)(8)
- 《c語言程序設(shè)計》
- c語言程序設(shè)計(第3版)何欽銘-顏-暉-第2章--c語言編寫程序
- c語言程序設(shè)計
- c語言程序設(shè)計
- c語言程序設(shè)計
- c語言程序設(shè)計
- c語言程序設(shè)計教程 (第2版)
- 第3章java語言程序設(shè)計基礎(chǔ)
- 第二章、c語言程序設(shè)計基礎(chǔ)
- c語言程序設(shè)計第七章數(shù)組
- c語言程序設(shè)計(譚浩強(qiáng))
評論
0/150
提交評論