第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)_第1頁
第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)_第2頁
第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)_第3頁
第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)_第4頁
第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)_第5頁
已閱讀5頁,還剩382頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第3章面向?qū)ο蟪绦蛟O(shè)計(jì)語言基礎(chǔ)3.1面向?qū)ο蟪绦蛟O(shè)計(jì)語言3.2C++語言基礎(chǔ)3.3Java的基礎(chǔ)知識(shí)3.1面向?qū)ο蟪绦蛟O(shè)計(jì)語言掌握面向?qū)ο蟪绦蛟O(shè)計(jì),首先應(yīng)該學(xué)習(xí)面向?qū)ο蟪绦蛟O(shè)計(jì)語言。當(dāng)今有很多種編程語言能體現(xiàn)基本的面向?qū)ο笏枷耄鏑++、Java、Smalltalk、CLOS等,但普遍被推崇的、流行的有兩種,即C++和Java。下面將介紹C++和Java的一些基礎(chǔ)知識(shí)。3.1.1程序程序是有目的的動(dòng)作序列,它是一種軟件。對于程序員來說,程序是以某種語言為工具編制出來的動(dòng)作序列,它表達(dá)了人解決現(xiàn)實(shí)世界問題的思想。計(jì)算機(jī)程序是用計(jì)算機(jī)程序設(shè)計(jì)語言所要求的規(guī)范書寫出來的一系列動(dòng)作,它表達(dá)了程序員要求計(jì)算機(jī)執(zhí)行的操作。對于計(jì)算機(jī)來說,一組機(jī)器指令就是程序。我們所說的機(jī)器代碼或者機(jī)器指令,都是指程序,它是按計(jì)算機(jī)硬件設(shè)計(jì)規(guī)范的要求編制出來的動(dòng)作序列。在計(jì)算機(jī)中,程序通常以文件的形式保存。3.1.2語言及其分類語言按其等級可分為高級語言和低級語言。機(jī)器語言和匯編語言都是低級語言。程序語言越低級,程序的描寫越復(fù)雜,越難懂,程序描述的問題越接近機(jī)器。最早,程序員使用最原始的計(jì)算機(jī)指令,即機(jī)器語言程序。只有機(jī)器語言才能被機(jī)器識(shí)別和運(yùn)行,這些指令以一串二進(jìn)制數(shù)表示。不久,發(fā)明了匯編語言,它可以將機(jī)器指令映射為一些能被人讀懂的助記符。以后,各種高級語言迅速發(fā)展起來。發(fā)展過程中,經(jīng)歷了嚴(yán)酷的優(yōu)勝劣汰過程,最后剩下一些比較優(yōu)秀的高級語言。C++作為一種多范型語言,就是一種優(yōu)秀的高級語言。例如,我們用C++和匯編語言分別來實(shí)現(xiàn)表達(dá)式a=2b+3c?1,用C++實(shí)現(xiàn)為a=2*b+3*c?1;用匯編來實(shí)現(xiàn)為

moveax,DWORDPTRb_$[ebp]movecx,DWORDPTRc_$[ebp]muleax,2mulecx,3addeax,ecxdeceaxmovDWORDPTRb_$[ebp],eax語言越低級,就表明越靠近機(jī)器;越高級,就表明越靠近人的表達(dá)與理解、越自然。程序語言的發(fā)展,是從低級到高級,直到可用人的自然語言來描述。程序語言的發(fā)展也是從具體到抽象的發(fā)展過程。從上面的例子中可以看出,作為高級語言的C++在實(shí)現(xiàn)表達(dá)式時(shí)要比匯編語言簡潔得多。3.1.3C++是面向?qū)ο蟪绦蛟O(shè)計(jì)語言正如第1、2章所述,程序設(shè)計(jì)方法正在從結(jié)構(gòu)化程序設(shè)計(jì)走向面向?qū)ο蟪绦蛟O(shè)計(jì)。C語言能夠很好地支持結(jié)構(gòu)化范型程序設(shè)計(jì),而C++能夠很好地支持面向?qū)ο蠓缎统绦蛟O(shè)計(jì)。在第4、5章中將介紹用C++來實(shí)現(xiàn)面向?qū)ο蠓缎偷某绦蛟O(shè)計(jì)。3.2C++語言基礎(chǔ)3.2.1C++的發(fā)展史

C++僅有二十幾年的歷史,它是C語言的擴(kuò)展和完善。C語言是貝爾實(shí)驗(yàn)室的DennisRitchie在B語言的基礎(chǔ)上開發(fā)出來的。1972年在一臺(tái)DECPDP-11計(jì)算機(jī)上實(shí)現(xiàn)了最初的C語言。到20世紀(jì)70年代末,C已經(jīng)演化為現(xiàn)在所說的“傳統(tǒng)的C語言”。Kernighan和Ritchie在1978年出版的《TheCProgrammingLanguage》一書中全面地介紹了傳統(tǒng)的C語言,1989年美國國家標(biāo)準(zhǔn)協(xié)會(huì)制定了C語言的標(biāo)準(zhǔn)(ANSIC)。Kernighan和Ritchie編著的第二版《TheCProgrammingLanguage》(1988年版)介紹了ANSIC的全部內(nèi)容。至此,C語言以其如下獨(dú)有的特點(diǎn)風(fēng)靡了全世界:(1)語言簡潔、緊湊,使用方便、靈活。C語言只有32個(gè)關(guān)鍵字,程序書寫形式自由。(2)豐富的運(yùn)算符和數(shù)據(jù)類型。(3)C語言可以直接訪問內(nèi)存地址,能進(jìn)行位操作,能夠勝任開發(fā)操作系統(tǒng)的工作。(4)生成的目標(biāo)代碼質(zhì)量高,程序運(yùn)行效率高。(5)可移植性好。

C語言盛行的同時(shí),也暴露出了其局限性:(1)類型檢查機(jī)制相對較弱,這使得程序中的一些錯(cuò)誤不能在編譯時(shí)發(fā)現(xiàn);(2)C本身幾乎沒有支持代碼重用的語言結(jié)構(gòu),因此一個(gè)程序員精心設(shè)計(jì)的程序很難為其他程序所用;(3)當(dāng)程序的規(guī)模達(dá)到一定的程度時(shí),程序員很難控制程序的復(fù)雜性。為滿足管理程序復(fù)雜性的需要和克服C語言的以上缺點(diǎn),就必須對C語言進(jìn)行完善或以一種新的語言來代替C語言,C++就是在這種環(huán)境下應(yīng)運(yùn)而生的。1980年,貝爾實(shí)驗(yàn)室的BjarneStroustrnp開始對C進(jìn)行改進(jìn)和擴(kuò)充。最初的成果稱為“帶類的C”,1983年正式取名為C++。在對C++進(jìn)行了三次修訂后,于1994年制定了ANSIC++標(biāo)準(zhǔn)的草案,以后又經(jīng)過不斷完善成為目前的C++。C++仍在不斷發(fā)展中。

C++包含了整個(gè)C,C是建立C++的基礎(chǔ);添加了對面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)的完全支持。下面介紹在用C++來實(shí)現(xiàn)面向?qū)ο蟪绦蛟O(shè)計(jì)中,必須掌握的C++的關(guān)于支持面向?qū)ο蠓矫娴鹊恼Z法基礎(chǔ)。對C缺乏了解的讀者,建議在本書之外,盡快瀏覽一下C語言的有關(guān)內(nèi)容。3.2.2C++基礎(chǔ)語法1.關(guān)鍵字關(guān)鍵字是預(yù)先定義好的標(biāo)識(shí)符,這些標(biāo)識(shí)符在C++編寫程序的時(shí)候,有特殊的含義。在C++中共有61個(gè)關(guān)鍵字。在程序設(shè)計(jì)的過程中應(yīng)注意,程序中用到的其他名字不能與這些關(guān)鍵字有相同的拼法(包括大小寫都不能相同)。表3-1給出了C++中定義的關(guān)鍵字。表3-1C++中定義的關(guān)鍵字staticautobreakunsignedprotectedconstuniondefaultdoubleelseexplictcontinuefloatforgotointlongregistervolatileshortsignedsizeofstructswitchtypedefoperatorcasevoidreturnboolcatchclassconst_castdeleteenumfalseinlinemutablenamespacedynamic_castnewexternprivatepublicthistemplatereinterpret_castthrowturetrytypenameusingvirtualstatic_castwchar_tdoifwhilefriendchartypeid

2.基本數(shù)據(jù)類型在程序中要用到數(shù)據(jù),數(shù)據(jù)常以變量或常數(shù)的形式來描述。每個(gè)變量或常數(shù)都有數(shù)據(jù)類型。變量是存儲(chǔ)信息的存儲(chǔ)單元,它對應(yīng)于某個(gè)內(nèi)存空間,用變量名代表其存儲(chǔ)空間,程序能在變量中存儲(chǔ)和取出值。數(shù)據(jù)類型用來告訴編譯器應(yīng)為變量分配多少內(nèi)存空間、怎樣組織已分配的內(nèi)存空間,以及變量中要存儲(chǔ)值的類型。數(shù)據(jù)類型分為基本數(shù)據(jù)類型和非基本數(shù)據(jù)類型。非基本數(shù)據(jù)類型包括數(shù)組、指針和結(jié)構(gòu)等類型?;緮?shù)據(jù)類型有char、int、float、double、wchar_t和bool等。圖3-1描述了C++的數(shù)據(jù)類型的分類。圖3-1中的type表示非空的數(shù)據(jù)類型,是程序員可以自己定義的數(shù)據(jù)類型。在圖3-1中只是給出了常用數(shù)據(jù)類型和部分?jǐn)?shù)據(jù)類型修飾符,它們用來改變基本類型的意義,用于適應(yīng)各種情況的需要。修飾符有l(wèi)ong(長型符)、short(短型符)、signed(有符號(hào))和unsigned(無符號(hào))等。數(shù)據(jù)類型修飾符確定了該數(shù)據(jù)所占內(nèi)存空間的大小和可表示的數(shù)值范圍。表3-2是16位計(jì)算機(jī)中各數(shù)據(jù)類型所能表示的數(shù)值范圍。圖3-1C++的數(shù)據(jù)類型表3-2常用基本數(shù)據(jù)類型描述類型說明長度(字節(jié))表示范圍備注char字符型1-128~127-27~(27-1)unsignedchar無符號(hào)字符型10~2550~(28-1)signedchar有符號(hào)字符型1-128~127-27~(27-1)int整型2-32?768~32?767-215~(215-1)unsignedint無符號(hào)整型20~65?5350~(216-1)signedint有符號(hào)整型2-32?768~32?767-215~(215-1)shortint短整型2-32?768~32?767-215~(215-1)longint長整型4-2?147?183?648~2?147?483?647-231~(231-1)float浮點(diǎn)型(單精度)4-3.4×1038~3.4×10387位有效位double雙精度8-1.7×1038~1.7×103815位有效位longdouble長雙精度16-3.4×104932~3.4×10493219位有效位3.變量定義1)變量名的命名C++中變量的命名應(yīng)該遵守以下規(guī)則:(1)不能是C++關(guān)鍵字;(2)第一個(gè)字符必須是字母或下劃線;(3)不要太長,一般不超過31個(gè)字符;(4)不能以數(shù)字開頭;(5)中間不能有空格;(6)變量名中不能包含“.;,"'+?'之類的特殊符號(hào)。(7)變量名不要與C++中庫函數(shù)名、類名、和對象名相同。2)變量定義方式在給變量命名時(shí),通常用帶有描述性的字符串,例如用area命名一個(gè)面積變量,用time命名時(shí)間變量。這些變量在應(yīng)用時(shí),程序員和讀者對其意義一目了然。例如:

intnumber;doublesum;floatlength;

3)變量賦值與初始化用賦值運(yùn)算符“=”給變量賦值。變量初始化是指在定義變量時(shí)直接給變量賦值,也可以先定義變量,然后用賦值語句給其賦值。并不是所有的變量都需要初始化,未初始化的變量在編譯器編譯時(shí)并不會(huì)出錯(cuò)。例如:

unsignedshortwidth;doublearea,radius=23;width=4;

其中,變量width先定義后賦值;而變量radius在定義時(shí)初始化;變量area未初始化。這些變量在編譯時(shí)均不會(huì)出現(xiàn)錯(cuò)誤。4)typedef

用typedef可以為一個(gè)已有的類型名提供一個(gè)同義詞,該同義詞可以代替該類型在程序中使用。用法是以typedef開始,隨后是要表示的類型,最后是同義詞和分號(hào)。typedef實(shí)際上沒有定義一個(gè)新的數(shù)據(jù)類型,在建立一個(gè)typedef類型時(shí)沒有分配內(nèi)存。例如:

typedefdoubleprofit;//定義double的同義類型

typedefintINT,integer;//定義int的兩個(gè)同義類型

INTa; //同inta;integera; //同inta;profitd; //同doubled;3.2.3常數(shù)1.實(shí)數(shù)常數(shù)實(shí)數(shù)常數(shù)的表示方法有兩種:(1)十進(jìn)制小數(shù)。它由數(shù)字和小數(shù)點(diǎn)組成,如0.123,0.234,0.0等都是十進(jìn)制數(shù)。(2)指數(shù)形式。如:425e4或425E4表示425×104。要注意E或e的前面必須是數(shù)字,且E或e后面的指數(shù)必須為整數(shù)。實(shí)數(shù)型常數(shù)常分為單精度(float)、雙精度(double)和長雙精度(longdouble)3類。在16位計(jì)算機(jī)中,float型數(shù)據(jù)在內(nèi)存中占4個(gè)字節(jié),double型數(shù)據(jù)在內(nèi)存中占8個(gè)字節(jié),longdouble數(shù)據(jù)類型在內(nèi)存中占16個(gè)字節(jié)。float型提供7位有效數(shù)字,double型提供15位有效數(shù)字,longdouble提供19位有效數(shù)字。在C++中,一個(gè)實(shí)數(shù)如果沒有說明,則其類型為默認(rèn)類型double型。要表示float型數(shù),則必須在實(shí)數(shù)后面加上F或f;要表示longdouble型數(shù),則必須在實(shí)數(shù)后面加上L或l。例如:3.2f //float型實(shí)數(shù)3.2L

//longdouble型實(shí)數(shù)3.2 //沒有說明,故為默認(rèn)類型double型2.字符常數(shù)字符常數(shù)是用單引號(hào)括起來的一個(gè)字符,它分為一般字符常數(shù)和特殊字符常數(shù)。一般字符常數(shù)有a、x等字符,特殊字符常數(shù)是以“\”開頭的字符。表3-3列出了常用的特殊字符。表3-3常用的特殊字符字符形式值功能\a0x07響鈴\n0x0A換行\(zhòng)t0x09制表符(橫向跳格)\v0x0B豎向跳格\b0x08退格\r0x0D回車\\0x5C反斜杠字符“\”\"0x22雙引號(hào)\'0x27單引號(hào)\ddd

1~3位八進(jìn)制\xhh

1~2位十六進(jìn)制表中列出的字符又稱為轉(zhuǎn)義字符,即將反斜杠后面的字符轉(zhuǎn)變成另外的意義。有些是控制字符,如“\n”;有些字符是在該字符前加轉(zhuǎn)義字符來表示的,如“\”、“'”、“"”。在內(nèi)存中,字符數(shù)據(jù)以ASCII碼存儲(chǔ),即以整數(shù)表示,所以字符數(shù)據(jù)和整型數(shù)據(jù)在0~255(一個(gè)字節(jié)范圍內(nèi))之間可以相互賦值。只要注意其表示的范圍合理即可。例如:

inta='b'; //正確,將整型變量賦一個(gè)字符值(b的ASCII值為98)

charc=97; //正確,將一個(gè)字符變量賦一個(gè)整型值(97代表的ASCII字符是a)

在下列C++語句中,將自動(dòng)根據(jù)變量定義時(shí)的數(shù)據(jù)類型,來確定輸出的究竟是字符類型值還是整型類型值。例如:

cout<<a<<endl; //輸出字符b的ASCII值98

cout<<c<<endl; //輸出ASCII值97的字符b

上面兩行語句自動(dòng)根據(jù)a或c被定義的數(shù)據(jù)類型確定其輸出結(jié)果及類型。3.字符串常數(shù)字符串常數(shù)是由一對雙引號(hào)括起來的字符序列,字符串常數(shù)和字符常數(shù)是不同的,字符串常數(shù)總是以“\0”結(jié)束。如果一個(gè)字符串常數(shù)為“welcome”,那么它在內(nèi)存中占用連續(xù)8個(gè)內(nèi)存字節(jié)。在編程時(shí)應(yīng)注意變量類型的匹配,不能將字符串常數(shù)賦給字符變量。4.枚舉常數(shù)枚舉常數(shù)是通過關(guān)鍵字enum來定義的。定義的格式為以enum開始,后跟類型名和花括號(hào)。花括號(hào)內(nèi)是要定義的枚舉常數(shù)(又稱為助記常數(shù),該助記常數(shù)往往代表一個(gè)整型常數(shù)值),各常數(shù)之間用逗號(hào)分隔,最后以分號(hào)結(jié)束。例如:enumCOLOR{RED=150,BULE=200,GREEN,WHITE=400};

其中,有一個(gè)枚舉常數(shù)BLUE,代表200;GREEN沒有被顯式寫出,在編譯時(shí)其值自動(dòng)被確定為201。如果沒有顯式地為枚舉常量確定值,C++會(huì)為其自動(dòng)確定,即花括號(hào)后的第一個(gè)枚舉常數(shù)會(huì)被確定為0,其后的每個(gè)枚舉常數(shù)的值為前一個(gè)枚舉常數(shù)值加1。在下面程序中,企圖用賦值語句給枚舉變量賦值為不是定義枚舉類型時(shí)規(guī)定的值,是不正確的。

COLORpaint=BULE; //正確

piant=200;//錯(cuò)誤,因?yàn)?00不是規(guī)定的枚舉類型常數(shù)5.常量定義

C++中,常量是代表固定值的變量,即表示變量的值已被固定。程序中如果想讓變量內(nèi)容初始化后一直保持不變,則可以將其定義成一個(gè)常量。本書對常量與常數(shù)進(jìn)行了區(qū)分(這與其他書有所不同),常數(shù)代表了書寫時(shí)的字面含義。常量定義的格式是:在關(guān)鍵字const后接變量名,然后是常數(shù)值,最后以分號(hào)結(jié)束該語句。例如:

constfloatpi=3.1415926;在定義了常量pi之后,就可以在程序中用pi來代替3.1415926。常量不能放在賦值語句的左邊,即常量不能被賦值。常量定義中初始化的值可以是一個(gè)由常數(shù)和操作符構(gòu)成的表達(dá)式。在程序運(yùn)行之前就已經(jīng)知道了常量值,因此編譯時(shí)就能求值。注意:該表達(dá)式中不能含有函數(shù),例如:

constintsize=20*sizeof(int); //oksizeof是運(yùn)算符

constintnumber=max(23,34); //錯(cuò)誤6.引用引用是變量的別名,用&符號(hào)來聲明。對別名的存取就是對變量的存取。別名沒有存儲(chǔ)空間,對引用聲明的同時(shí)需對其進(jìn)行初始化。例3.1引用實(shí)例。intx=10;int&y=x; //聲明y是x的引用cout<<y<<endli; //y=10x=20;cout<<y<<endl; //y=20;y=30;cout<<x<<endl; //x=30使用引用比C語言中用指針來實(shí)現(xiàn)兩數(shù)交換容易理解且語句簡潔。例如:voidswap(int&xx,int&yy){inttemp;temp=xx;xx=yy;temp=xx;}voidmain(){inta=10,b=20;cout<<a<<"--"<<b<<endl;swap(a,b);//直接用a、b作為實(shí)參,而C語言用指針實(shí)現(xiàn)交換時(shí),要用其地址

cout<<a<<"--"<<b<<endl;}3.2.4輸入/輸出1.輸入/輸出(I/O)的書寫格式

I/O流是輸入或輸出的一系列字節(jié)。當(dāng)程序需要在屏幕上顯示輸出時(shí),使用操作符“<<”向cout輸出流中插入字符;當(dāng)程序需要執(zhí)行從鍵盤輸入時(shí),使用操作符“>>”從cin輸入流中輸入字符。

例3.2I/O書寫格式實(shí)例。#include<iostream.h>voidmain(){charch;cout<<"inputthecharacteryouwanttoprint:"<<endl;cin>>ch;cout<<ch<<endl;}程序運(yùn)行結(jié)果為:

inputthecharacteryouwanttoprint:aa

cout代表I/O的輸出對象(默認(rèn)為屏幕),在例3.2中它輸出一行提示語句;cin代表I/O的輸入對象,在例3.2中從鍵盤輸入了一個(gè)字符a,最后我們有一行輸出語句輸出所輸入的字符。頭文件iostream.h包含涉及cout和cin的一些必要的定義內(nèi)容。在輸入和輸出時(shí)還可以使用控制符來控制輸入/輸出的格式,以滿足輸入/輸出的需要,表3-4中列出了常用輸入/輸出控制符。表3-4常用輸入/輸出控制符控制符描述dec置基數(shù)為10hex置基數(shù)為16oct置基數(shù)為8setfill設(shè)置填充字setiosflags(ios::fixed)固定的浮點(diǎn)顯示etw設(shè)置小數(shù)精度setiosflags(ios::left)左對齊setiosflags(ios::right)右對齊setiosflags(ios::scientific)指數(shù)表示setiosflags(ios::skipws)忽略前導(dǎo)空白setiosflags(ios::uppercase)十六進(jìn)制數(shù)大寫輸出setiosflags(ios::lowercase)十六進(jìn)制小寫輸出3.2.5表達(dá)式和語句程序是一些按次序執(zhí)行的語句,而大部分的語句是由表達(dá)式構(gòu)成的。表達(dá)式和語句是C++的重要內(nèi)容。表達(dá)式由操作符、操作數(shù)構(gòu)成,其目的是用來說明一個(gè)計(jì)算過程。在C++中操作符的優(yōu)先級和結(jié)合性等規(guī)則與C語言是完全一致的,使用方法與C語言中表達(dá)式的使用方法也是相同的。

C++中所有的操作運(yùn)算都是通過表達(dá)式來實(shí)現(xiàn)的。由表達(dá)式組成的語句稱為表達(dá)式語句,由一個(gè)表達(dá)式和一個(gè)分號(hào)組成。大多數(shù)表達(dá)式語句是賦值語句和函數(shù)調(diào)用語句。語句用來規(guī)定程序執(zhí)行的控制流。復(fù)合語句又被稱為塊,它是一對花括號(hào)內(nèi)的語句序列。C++中的語句和C語言中的語句是大致相同的,其使用方法也是一樣的,在本書中不再贅述。下面對過程化語句進(jìn)行介紹。1.過程化語句

語句按功能可分為兩大類:第一大類用于描述計(jì)算機(jī)執(zhí)行的操作運(yùn)算,即操作語句;第二大類用于控制操作運(yùn)算的執(zhí)行順序的控制語句,即流程控制語句。流程控制語句也被稱為過程化語句。圖3-2while語句的流程結(jié)構(gòu)1)while語句

while語句由4個(gè)部分組成:循環(huán)變量初始化、繼續(xù)條件、循環(huán)體、改變循環(huán)變量的算法。while用于判斷一個(gè)條件表達(dá)式,當(dāng)條件成立的時(shí)候進(jìn)入循環(huán)體,不滿足這個(gè)條件則不進(jìn)入循環(huán)體。while語句的流程結(jié)構(gòu)如圖3-2所示。例3.3while語句應(yīng)用實(shí)例。voidmain(){intj=1;intsum;while(j<=50){sum=sum+j;j++;}cout<<"sum="<<sum<<endl;}2)do-while語句do-while語句的格式如下:do循環(huán)體while(條件表達(dá)式);當(dāng)流程到達(dá)do后,立即執(zhí)行循環(huán)體語句,然后對條件表達(dá)式進(jìn)行測試,如滿足條件,則重復(fù)循環(huán),否則退出,該語句結(jié)構(gòu)至少使循環(huán)體執(zhí)行一次。do-while語句的流程結(jié)構(gòu)如圖3-3所示。圖3-3do-while語句的流程結(jié)構(gòu)例3.4do-while語句應(yīng)用實(shí)例。#include<iostream.h>voidmain(){intj,sum=0;j=1;do{sum=sum+j;j++;}while(j<=50)

cout<<"sum="<<sum<<endl;}

例3.3和例3.4都是求sum=1+2+…+50的和的程序,它們使用了不同的循環(huán)控制語句,但結(jié)果是相同的。3)for語句for語句也可以用來控制循環(huán),for語句的格式如下:for(表達(dá)式1;表達(dá)式2;表達(dá)式3)循環(huán)體for語句的執(zhí)行過程如下:(1)求解表達(dá)式1;(2)求解表達(dá)式2,若為0則結(jié)束循環(huán)轉(zhuǎn)到(5);(3)若表達(dá)式2為真,則執(zhí)行循環(huán)體,然后求解表達(dá)式3;(4)轉(zhuǎn)回(2);(5)執(zhí)行for語句下面的語句。圖3-4for語句的流程結(jié)構(gòu)

for語句的流程結(jié)構(gòu)如圖3-4所示。在使用for語句時(shí),并不是每個(gè)表達(dá)式都必須賦值,并且每個(gè)表達(dá)式都可以省略,但在省略表達(dá)式時(shí),應(yīng)該注意一些問題:在省略表達(dá)式1時(shí),控制變量應(yīng)該在使用之前的程序中被初始化;省略表達(dá)式2,即不進(jìn)行判斷而使循環(huán)不停的進(jìn)行下去,這樣在循環(huán)體中需要有跳出循環(huán)的控制語句,否則就會(huì)出現(xiàn)死循環(huán);在省略表達(dá)式3時(shí),應(yīng)該注意必須另外設(shè)法使循環(huán)控制變量變化,以保證循環(huán)能正常結(jié)束。不僅每個(gè)表達(dá)式可以單獨(dú)省略,而且它們可以同時(shí)省略。在省略表達(dá)式時(shí),應(yīng)注意表達(dá)式后面的分號(hào)不能省略。例3.5for語句應(yīng)用實(shí)例。i=0;for(;i<=10;) //分號(hào)不能省略sum+=i++; //求值的同時(shí)改變循環(huán)變量//省略所有的表達(dá)式i=0;for(;;){sum+=i++; //求值的同時(shí)改變循環(huán)控制變量if(i>10) //控制結(jié)束條件break; //當(dāng)i大于10時(shí)循環(huán)結(jié)束,跳出循環(huán)體}在本例中省略了表達(dá)式1和表達(dá)式3。4)switch語句當(dāng)要實(shí)現(xiàn)多分支選擇語句時(shí),就要用到switch語句。switch的格式如下:switch(表達(dá)式){case常量表達(dá)式1:執(zhí)行語句1case常量表達(dá)式2:執(zhí)行語句2

case常量表達(dá)式n:執(zhí)行語句ndefault:執(zhí)行語句n+1}

switch后面括號(hào)中的表達(dá)式只能是整型、字符型或枚舉類型。case后面的常量表達(dá)式必須與表達(dá)式匹配,如果不匹配,則在編譯時(shí)會(huì)出現(xiàn)錯(cuò)誤。當(dāng)表達(dá)式的值與某一個(gè)case后面常量表達(dá)式的值相等時(shí),就執(zhí)行case后面的語句,若沒有與之匹配的常量表達(dá)式,則執(zhí)行default后的執(zhí)行語句。例3.6switch語句應(yīng)用實(shí)例。#include<iostream.h>voidmain(){chargrade;cin>>grade;switch(grade){case'A':cout<<"85-100"<<endl;break;case'B':cout<<"70-84"<<endl;break;case'C':cout<<"60-69"<<endl;break;case'D':cout<<"<60"<<endl;break;default:cout<<"error"<<endl;}}在本例中,當(dāng)輸入一個(gè)字符時(shí)如果它與A、B、C、D中的任何一個(gè)匹配,則輸出其后對應(yīng)的語句;若不能與它們之中的任何一個(gè)匹配,則輸出default后的語句,即輸出出錯(cuò)提示error。請讀者自行分析break語句的作用。現(xiàn)在我們已經(jīng)了解了C++的基本語法,下面具體分析幾個(gè)例子。例3.7判明素?cái)?shù)并輸出100內(nèi)中所有的素?cái)?shù)。在判斷一個(gè)數(shù)m是否是素?cái)?shù)時(shí),就是檢驗(yàn)它是否能被2~中的任意一個(gè)整數(shù)整除。如果存在一個(gè)數(shù)在范圍2~內(nèi)且能整除m,則m不是素?cái)?shù);否則,m是素?cái)?shù)。#include<iostream.h>#include<math.h>voidprime(longm){intsqrtm;sqrtm=sqrt(m);for(inti=2;i<=sqrtm;i++)if(m%i==0)break;if(sqrtm<i)cout<<m<<endl;elsecout<<m<<"itisnotaprime"<<endl;}voidmain(){longm;cout<<"inputthenumberm:"<<endl;cin>>m;

prime(m);for(intj=1;j<=100;j++)prime(j);}

函數(shù)prime()用來判斷一個(gè)數(shù)是否是素?cái)?shù)。如果是,則輸出該數(shù);如果不是,則輸出“itisnotaprime”。在尋找1~100內(nèi)中的素?cái)?shù)時(shí),我們用了一個(gè)循環(huán)語言來控制輸入的數(shù)為1~100,然后判斷每個(gè)數(shù)是否為素?cái)?shù)。例3.8猴子吃桃問題。猴子第一天摘下若干桃子,當(dāng)即吃了一半,還不過癮,又多吃了一個(gè)。第二天早晨又將剩下的桃子吃掉一半,又多吃了一個(gè)。以后每天早上都吃了前一天剩下來的一半又多一個(gè)。這樣,到第10天早晨想再吃時(shí),發(fā)現(xiàn)只剩下一個(gè)桃子了,問猴子第一天摘了多少個(gè)桃子。這個(gè)問題用程序能很輕易的解決,只需要用一個(gè)循環(huán)語句構(gòu)成的函數(shù)就可以實(shí)現(xiàn)。#include<iostream.h>intfn(intm){m=2*m;m++;returnm;}voidmain(){floatsum=1;for(inti=1;i<10;i++)sum=fn(sum);cout<<sum<<endl;}輸出結(jié)果為1023,這和用手工計(jì)算得到的值是一致的。在解決這個(gè)問題時(shí),考慮到從第10天的桃子數(shù)起,以后每天的桃子數(shù)是后一天的2倍多一個(gè),這樣就能用循環(huán)語句方便地解決這個(gè)問題。3.2.6函數(shù)

要編好程序,就要合理地劃分程序中的各個(gè)程序塊,即函數(shù)。C++程序是由函數(shù)組成的,一個(gè)C++程序由一個(gè)或若干個(gè)函數(shù)構(gòu)成,程序中的函數(shù)在程序運(yùn)行時(shí)被調(diào)用,雖然main()也是函數(shù),但它并不是普通的函數(shù),它表示程序的入口。程序命令按照它們在源代碼中出現(xiàn)的順序一行行地順序執(zhí)行,直到遇到新的函數(shù)調(diào)用,然后程序分支去執(zhí)行函數(shù)調(diào)用。當(dāng)函數(shù)調(diào)用完成時(shí),程序控制立即返回調(diào)用函數(shù)下一行代碼。圖3-5C++程序中函數(shù)調(diào)用層次圖在C++中,一個(gè)函數(shù)必須在聲明后才能使用。函數(shù)聲明的作用是告訴編譯器,該函數(shù)是存在的。以后編譯器在遇到該函數(shù)被調(diào)用時(shí)就不會(huì)出錯(cuò)了,同時(shí)編譯器還對函數(shù)調(diào)用進(jìn)行正確性檢查。C++函數(shù)聲明總是由函數(shù)原型構(gòu)成的。

C++程序中函數(shù)調(diào)用的層次如圖3-5所示。1.函數(shù)原型

C++中的函數(shù)分為兩種:標(biāo)準(zhǔn)庫函數(shù)和用戶自定義的函數(shù)。標(biāo)準(zhǔn)庫函數(shù)在使用前可以用包含指令#include包含在頭文件中,而用戶自己定義的函數(shù)在使用前必須先聲明,即在使用前說明函數(shù)的原型。函數(shù)原型是一條程序語句,必須以分號(hào)結(jié)束。它由函數(shù)返回類型、函數(shù)名和參數(shù)構(gòu)成,其形式為返回類型function(參數(shù)表);參數(shù)表包含所有參數(shù)的數(shù)據(jù)類型,各參數(shù)之間用逗號(hào)分開。函數(shù)原型與函數(shù)定義在返回類型、函數(shù)名和參數(shù)表上必須完全一致。函數(shù)的返回值也稱為函數(shù)值,返回的不是函數(shù)本身而是一個(gè)值。我們經(jīng)常用return語句來返回函數(shù)的值。在使用函數(shù)時(shí)會(huì)涉及到變量的使用,在C++中變量的作用域和使用規(guī)則與C語言中是完全相同的,本書中不再贅述。2.函數(shù)的調(diào)用機(jī)制

C++中函數(shù)的調(diào)用過程就是??臻g操作的過程。在函數(shù)調(diào)用時(shí),C++會(huì)進(jìn)行如下操作:(1)建立被調(diào)用函數(shù)的??臻g;(2)保護(hù)調(diào)用函數(shù)的運(yùn)行狀態(tài)和返回地址;(3)傳遞參數(shù);(4)將控制轉(zhuǎn)交給被調(diào)函數(shù)。例3.9函數(shù)調(diào)用實(shí)例。voidarea(int,int);voidsum(float,float);voidmain(){inta=4,b=5;area(a,b);sum(a,b);}在主函數(shù)調(diào)用兩個(gè)函數(shù)之前,先對這兩個(gè)函數(shù)的原型進(jìn)行了聲明。主函數(shù)中調(diào)用了兩個(gè)函數(shù),其調(diào)用過程實(shí)際上就是一個(gè)對棧的操作過程。其他函數(shù)調(diào)用如遞歸調(diào)用在C語言中也有詳細(xì)的敘述。關(guān)于函數(shù)還應(yīng)注意:任何函數(shù)之間不能嵌套定義,調(diào)用函數(shù)與被調(diào)用函數(shù)相互獨(dú)立,被調(diào)用函數(shù)和調(diào)用函數(shù)之間是靠參數(shù)傳遞和返回值來聯(lián)系的,函數(shù)被看作為一個(gè)黑盒。3.內(nèi)聯(lián)函數(shù)函數(shù)調(diào)用需要建立棧內(nèi)存環(huán)境,進(jìn)行參數(shù)傳遞,并產(chǎn)生程序執(zhí)行轉(zhuǎn)移。這些工作都需要一定的時(shí)間開銷,若多次調(diào)用一個(gè)代碼很短的函數(shù),就會(huì)使程序的運(yùn)行效率降低。為解決這個(gè)問題,應(yīng)該使用內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)也稱為內(nèi)嵌函數(shù),是能提高程序的效率的一種特殊函數(shù)。內(nèi)聯(lián)函數(shù)用關(guān)鍵字inline來聲明,其具體的形式如下:

inline返回類型函數(shù)名(參數(shù)表){//函數(shù)體}在編譯時(shí)編譯器看到關(guān)鍵字inline后就為該函數(shù)創(chuàng)建一段代碼,在以后每次調(diào)用該函數(shù)時(shí),都會(huì)用這段代碼來替代相應(yīng)的函數(shù)。內(nèi)聯(lián)函數(shù)可以在一開始僅聲明一次。內(nèi)聯(lián)函數(shù)中不能含有復(fù)雜的結(jié)構(gòu)控制語句,如switch和while,若含有這些語句,在編譯時(shí)會(huì)將該函數(shù)視為普通函數(shù)一樣產(chǎn)生函數(shù)調(diào)用代碼;內(nèi)聯(lián)函數(shù)不能用作遞歸函數(shù)來使用;內(nèi)聯(lián)函數(shù)的返回值類型總是整型。例3.10內(nèi)聯(lián)函數(shù)舉例。#include<iostream.h>inlineintisnumber(charch){return(ch>='0'&&ch<='9')?1:0;}voidmain(){charc;while((c=cin.getc())!='\n') //cin.getc()是用于調(diào)用輸入對象的成員函數(shù){if(isnumber(c)) //調(diào)用一個(gè)小函數(shù)cout<<"youenteredadigit"<<endl;elsecout<<"youenteredanon-digit"<<endl;}}3.2.7函數(shù)的重載在C語言中,每個(gè)函數(shù)都必須有惟一的名字。為功能近似的問題定義函數(shù)時(shí),不得不為這些既近似又有區(qū)別的問題定義多個(gè)函數(shù),為這些函數(shù)起不同的函數(shù)名。C++允許這些不同的函數(shù)使用相同的函數(shù)名。在函數(shù)調(diào)用時(shí)根據(jù)給定的實(shí)際參數(shù)自動(dòng)匹配,究竟該調(diào)用哪一個(gè)函數(shù)。其匹配是嚴(yán)格按照這些函數(shù)定義時(shí)的參數(shù)類型、個(gè)數(shù)、順序來確定的。例3.11函數(shù)重載舉例。intabs(int);doubleabs(double);longabs(long);main(){abs(5); //自動(dòng)匹配調(diào)用intabs(int)函數(shù)}這三個(gè)函數(shù)具有相同的名字,但它們的參數(shù)類型不相同。重載函數(shù)的匹配順序是靠將實(shí)參類型與所有被調(diào)用的具有相同函數(shù)名的函數(shù)的形參類型一一比較來判定的。它們在匹配時(shí)按以下的順序來尋找被匹配的函數(shù):(1)尋找一個(gè)嚴(yán)格的匹配,如果找到了,就用那個(gè)函數(shù);(2)通過內(nèi)部轉(zhuǎn)換尋求一個(gè)匹配,只要找到了,就用那個(gè)函數(shù);(3)通過用戶定義的轉(zhuǎn)換尋求一個(gè)匹配,若能查出有惟一的一組轉(zhuǎn)換,就用那個(gè)函數(shù)。在大多數(shù)情況下,函數(shù)的匹配是用尋找一個(gè)嚴(yán)格的匹配進(jìn)行的。對于其它匹配,本書不述及。在匹配函數(shù)時(shí),如果調(diào)用函數(shù)的實(shí)際參數(shù)與所有的重載函數(shù)在參數(shù)類型、參數(shù)個(gè)數(shù)、參數(shù)順序上都不相同,則認(rèn)為不能匹配。編譯器無法分辨兩個(gè)完全一樣的重載函數(shù),因此重載函數(shù)應(yīng)該在參數(shù)個(gè)數(shù)、參數(shù)類型或參數(shù)順序上有所不同。

C++是C的完善,因此C++繼承了C的許多知識(shí)點(diǎn)。數(shù)組、指針、引用、結(jié)構(gòu)體以及它們的使用范圍和使用方法,在C++中與C中是完全相同的。

C++除繼承C的所有知識(shí)外還有其自身的特點(diǎn)。正如前面章節(jié)所述及的,C++是支持多范型的語言。下面重點(diǎn)從實(shí)現(xiàn)面向?qū)ο蟮娜齻€(gè)主要特征來介紹C++的其他內(nèi)容。這三個(gè)主要特征為:(1)封裝;(2)繼承;(3)多態(tài)。3.2.8C++中的類學(xué)習(xí)了第1、2章,對類的概念已經(jīng)有了一個(gè)基本的了解,現(xiàn)在我們詳細(xì)描述C++類的語法,以及對類的一些簡單使用。

1.類的建立及其成員

C++中的類與C語言中的結(jié)構(gòu)體相似,類的定義方法如下:

classClassname

{//數(shù)據(jù)成員//成員函數(shù)

};其中,class為關(guān)鍵字,Classname為類名,在定義一個(gè)類時(shí)關(guān)鍵字和類名是必不可少的,一般用具有典型意義的名字來命名類。例如,定義一個(gè)學(xué)生類,可以用Student來命名。為編程的需要我們可以將類的成員定義成不同的存取屬性(public、private、protected),在后續(xù)章節(jié)我們將具體介紹各類存取屬性的使用范圍和使用方法。下面為大家介紹類的成員定義和類的作用域等。類似于函數(shù)聲明,類也有聲明,其形式如下:

classStudent;2.成員的定義在類中可以定義其數(shù)據(jù)成員和成員函數(shù),下面介紹類的成員的定義和使用。例3.12類的成員的定義和使用實(shí)例。#include<iostream.h>classStudent{

public:floatagre(floatmath,floatphy,floatEnglish,floatchinese){agv=(math+phy+English+chinese)/4;returnagv;}private:floatmath;floatphy;floatEnglish;floatchinese;floatagv;};在該例中我們定義了一個(gè)學(xué)生類,在類中又定義了一個(gè)成員函數(shù)agre()和5個(gè)成員變量。在定義成員函數(shù)和成員變量時(shí),使用了兩個(gè)關(guān)鍵字public和private,它們分別將成員函數(shù)聲明為公有成員,將數(shù)據(jù)成員聲明為私有成員。在定義類的成員時(shí),根據(jù)我們的需要可以用關(guān)鍵字private、public和protected來聲明成員的存取屬性。被private聲明后的成員,稱為私有成員,由該關(guān)鍵字聲明的成員僅被該類的成員函數(shù)調(diào)用;被protected聲明后的成員,稱為被保護(hù)成員,該成員除了能被該類的成員函數(shù)使用外,還有其他的用途;被public聲明后的成員,稱為公有成員,由它聲明的成員不僅能被該類的成員函數(shù)調(diào)用,而且還能被類外的函數(shù)調(diào)用。private聲明的成員和protected聲明的成員在這里沒有太大的區(qū)別,但在繼承中有較大的差別(詳見后續(xù)內(nèi)容)。3.類的作用域類的作用域是指類定義時(shí)一對花括號(hào)所形成的作用域。在該范圍內(nèi),類的成員對同一類的成員函數(shù)具有訪問權(quán)。類的所有成員位于這個(gè)類的作用域內(nèi)。類的所有成員是一個(gè)相關(guān)的整體,而類外的函數(shù)訪問類的作用域的成員時(shí)受到了限制。這種思想是把一個(gè)類的數(shù)據(jù)結(jié)構(gòu)和功能封裝起來,從而使得在類外訪問該類時(shí),必須使用專用的接口(接口在這里指類中被public聲明為公有的成員函數(shù))。例3.13類的作用域舉例。classX{public:voidfn1(){n++;};voidfn2(){fn1();};intfn(){returnn;};private:intn;};4.類的封裝通過第1、2章的學(xué)習(xí),我們了解了封裝的概念,下面用一個(gè)具體的實(shí)例來介紹封裝是怎樣實(shí)現(xiàn)的。例3.14對“點(diǎn)”(Point)的封裝。

classPoint //Point的類定義{

public: //外部接口voidset(doubleix,doubleiy);doublexoffset();doubleyoffset();doubleangle();doubleradius();private: //內(nèi)部數(shù)據(jù)doublex; //橫坐標(biāo)doubley; //縱坐標(biāo)};//Point類的成員函數(shù)定義#include<math.h>#definepi3.1415926voidPoint::set(doubleix,doubleiy){x=ix;y=iy;}doublePoint::xoffset(){returnx;}doublePoint::yoffset(){returny;}doublePoint::angle(){return(180/pi)*atan2(y,x);}doublePoint::radius(){returnsqrt(x*y+y*y);}每個(gè)成員函數(shù)前都加了類名。要使用這段代碼,應(yīng)包含兩個(gè)頭文件,一個(gè)是point.h,因?yàn)樗谐蓡T函數(shù)的聲明都在類的定義中;另一個(gè)是math.h文件,因?yàn)樵诔蓡T函數(shù)的定義中調(diào)用了math.h中聲明的函數(shù)。在本例中我們將數(shù)據(jù)和操作結(jié)合,構(gòu)成了一個(gè)不可分割的整體,即類。用這個(gè)類可生成具有不同屬性值的對象。類中的一些數(shù)據(jù)成員是私有的,它們被有效的屏蔽,外界不會(huì)對其產(chǎn)生干擾和誤操作;另一些成員(成員函數(shù))是公共的,它們作為接口提供給外界使用。5.構(gòu)造函數(shù)和析構(gòu)函數(shù)在OOP中,凡是創(chuàng)建的對象都需要作某種形式的初始化。為此需要構(gòu)造函數(shù)(ConstructorFunction),供創(chuàng)建類的實(shí)例對象時(shí)調(diào)用,用以自動(dòng)完成對象的初始化。析構(gòu)函數(shù)(DestructorFunction)是與構(gòu)造函數(shù)相對應(yīng)的一個(gè)概念,它用于釋放對象定義時(shí)通過構(gòu)造函數(shù)向系統(tǒng)申請的存儲(chǔ)空間以及有關(guān)的系統(tǒng)資源,它是在其有效范圍內(nèi)自動(dòng)調(diào)用的。下面通過一個(gè)例子認(rèn)識(shí)構(gòu)造函數(shù)和析構(gòu)函數(shù)。例3.15構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。classStack{chararray[size];int*tos;~Stack();public:Stack(); //這是一個(gè)構(gòu)造函數(shù)viodpush(char);charpop(cahr);};Stack::Stack()//說明函數(shù)所屬的類且與類名相同{cout<<"constructingastack"<<endl;tos=newint[10]; //分配堆空間}Stack::~Stack(){cout<<"destructingstack"<<endl;deletetos; //釋放堆空間}通過該例我們對構(gòu)造函數(shù)和析構(gòu)函數(shù)有了一個(gè)初步的認(rèn)識(shí),下面再來對它們進(jìn)行詳細(xì)的討論。1)構(gòu)造函數(shù)的特性構(gòu)造函數(shù)是類的一個(gè)特殊的成員函數(shù),因此它除具有一般成員函數(shù)的受訪問限制、可重載等性質(zhì)外,還具有其自身的許多的特性:(1)構(gòu)造函數(shù)的名稱與它所屬的類名相同,在類對象被創(chuàng)建時(shí)自動(dòng)調(diào)用,它不能用常規(guī)的方法調(diào)用,不能被繼承;

(2)構(gòu)造函數(shù)無返回類型(任何返回類型,包括void,都是非法的),不能帶有return語句;(3)一個(gè)類可以具有多個(gè)構(gòu)造函數(shù),重載時(shí)參數(shù)的個(gè)數(shù)或類型應(yīng)不一樣,兩個(gè)具有相同參數(shù)類型和個(gè)數(shù)的構(gòu)造函數(shù)是非法的;(4)如果在編程時(shí)類中沒有顯式的定義構(gòu)造函數(shù),在編譯時(shí)系統(tǒng)會(huì)自動(dòng)的生成一個(gè)不帶任何參數(shù)的構(gòu)造函數(shù);(5)構(gòu)造函數(shù)在調(diào)用時(shí),控制成員變量的內(nèi)存分配,為定義的對象向系統(tǒng)申請內(nèi)存。

2)構(gòu)造函數(shù)的設(shè)計(jì)與使用類中的私有成員一般不作初始設(shè)置,需要在定義對象時(shí)初始化。采用顯式調(diào)用成員函數(shù)初始化對象容易遺漏,造成對象無意義,因此,使用構(gòu)造函數(shù)對對象進(jìn)行初始化是最佳選擇。同時(shí),一個(gè)類的不同對象需要有不同的初始化,因此可以采用帶參數(shù)的構(gòu)造函數(shù)和多構(gòu)造函數(shù)來解決這個(gè)問題。下面討論幾種構(gòu)造函數(shù)。(1)帶參數(shù)的構(gòu)造函數(shù)。例3.16帶參數(shù)的構(gòu)造函數(shù)舉例。classCourse{floatx,y;floatGDP;public:Course(ifloatox,floatoy);intGDP(floatx,floaty);};Course::Course(intx,inty){//以參數(shù)初始化變量

x=ox;y=oy;};intCourse::GDP(intx,inty){GDP=(x+y)/2;}voidmain(){CourseS(90,85);//定義對象時(shí)初始化S.GDP(90,85);}如果在定義對象S時(shí)不帶參數(shù),如CourseS;,那么,構(gòu)造函數(shù)就不能對x、y賦初值。構(gòu)造函數(shù)定義了缺省值,在函數(shù)調(diào)用時(shí),若無特別指定參數(shù),便以缺省值作初始化,而且也可以防止遺漏初始賦值。缺省參數(shù)的構(gòu)造函數(shù)的用法與一般函數(shù)的用法相同。例如將上述函數(shù)改為帶缺省參數(shù)的構(gòu)造函數(shù)如下:classCourse{floatx,y;floatGDP;public:Course(intox=90,oy=85){x=ox;y=oy;}

};(2)多構(gòu)造函數(shù)(構(gòu)造函數(shù)重載)。對于一個(gè)類的不同對象,當(dāng)其需要不同類型和不同個(gè)數(shù)的初始化參數(shù)時(shí),可以在一個(gè)類中定義幾個(gè)構(gòu)造函數(shù),以適應(yīng)不同的情況。例3.17多構(gòu)造函數(shù)舉例。

classCourse{public:Course();Course(float);Course(char,float);};voidmain(){Courseob1;Courseob2(78.5);Courseob3('M',87.5);}(3)復(fù)制構(gòu)造函數(shù)(CopyConstructor)。復(fù)制構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它除了具有一般構(gòu)造函數(shù)所具有的性質(zhì)外,還具有一些特殊的性質(zhì):①具有將參數(shù)傳輸對象按位拷貝的功能。②編譯系統(tǒng)在編譯類時(shí),產(chǎn)生一個(gè)缺省拷貝構(gòu)造函數(shù),例如,在main()中的語句

Courseob1('M',65.5);Courseob2(ob1);

對定義對象ob2,編譯系統(tǒng)自動(dòng)調(diào)用缺省拷貝構(gòu)造函數(shù),實(shí)現(xiàn)對象的按位拷貝。ob2與ob1完全相同,但它們是兩個(gè)完全獨(dú)立的對象。③程序員也可以自己定義拷貝構(gòu)造函數(shù),定義格式如下:

classname(constclassname&obj){…}

其中,obj是引用對象,可以用于初始化其他對象,若有其他參數(shù),則在此后列出,若缺省,則這個(gè)引用對象不能??;const是習(xí)慣上的限定詞(即習(xí)慣上將被拷貝對象聲明為不可改寫),obj對象也可以不是const型。例3.18拷貝構(gòu)造函數(shù)舉例。classCourse{charx;flaoty;public:Course(charox,floatoy){x=ox;y=oy;}Course(constcourse&M){x=M.x;y=M.y;}

};voidmain(){Courseob1('M',67.5);Courseob2(ob1);}注意:如果類中包含有指針成員,那么就要慎用缺省的拷貝構(gòu)造函數(shù),因?yàn)榫幾g器提供的拷貝構(gòu)造函數(shù)只是簡單的按位拷貝成員數(shù)據(jù),它會(huì)使兩個(gè)對象的指針指向同一片內(nèi)存區(qū)域,而不是復(fù)制指針指向的內(nèi)容。若該內(nèi)存區(qū)是動(dòng)態(tài)分配的,編程者有義務(wù)釋放它,但在釋放時(shí)會(huì)遇到麻煩,因?yàn)槠渲幸粋€(gè)指針被釋放后,另一個(gè)指針?biāo)傅膮^(qū)域就失去了意義,這可能會(huì)導(dǎo)致嚴(yán)重的后果。3)析構(gòu)函數(shù)的特性和用法析構(gòu)函數(shù)是用于當(dāng)對象離開其有效范圍時(shí),釋放對象所占用的內(nèi)存空間的一個(gè)特殊函數(shù)。析構(gòu)函數(shù)也是成員函數(shù),它是與構(gòu)造函數(shù)相對應(yīng)的,命名時(shí)在構(gòu)造函數(shù)名前加“~”。析構(gòu)函數(shù)只能是無返回類型,不能帶任何參數(shù),不能被重載,一個(gè)類只允許有一個(gè)析構(gòu)函數(shù)。析構(gòu)函數(shù)的定義一般是由一系列的delete組成的。例3.19析構(gòu)函數(shù)舉例。#include<iostream.h>#include<string.h>classsample{private:char*pointer_char;public:sample(){pointer_char=NULL;};sample(char*str){pointer_char=newchar[strlen(str)+1];strcpy(pointer_cahr,str);};sample(sample&ob){pointer_char=newchar[strlen(ob.pointer_char)+1];strcpy(pointer_char,ob.poiner_char);};~sample(){if(pointer_char!=NULL)deletepointer_char;};};3.2.9寫C++類代碼的相關(guān)基礎(chǔ)常識(shí)寫類代碼(主要考慮封裝性)會(huì)涉及到許多C++的語法知識(shí)細(xì)節(jié),本節(jié)敘述寫類代碼時(shí)應(yīng)該理解的其中一些基礎(chǔ)C++知識(shí)。對于在C++中表現(xiàn)繼承性和多態(tài)性的內(nèi)容,在后幾節(jié)將進(jìn)行討論。這些是面向?qū)ο蟪绦蛟O(shè)計(jì)的基礎(chǔ),要成為一個(gè)好的程序員,應(yīng)對其有一定了解。1.const對象和const成員函數(shù)對對象的最低訪問權(quán)是良好軟件工程的一項(xiàng)基本原則。下面講述的就是這一原則在對象上的應(yīng)用。某些對象是需要修改的,而有些對象是不需要修改的??梢栽诔绦蛑杏藐P(guān)鍵字const指明那些不允許修改的對象,任何試圖修改這種對象的嘗試都會(huì)導(dǎo)致編譯錯(cuò)誤。例如:

constTimenoon(12,0,0);

聲明了類Time的一個(gè)const對象,并把該對象初始化成時(shí)針為12點(diǎn)的時(shí)間。用const聲明某個(gè)對象可強(qiáng)制實(shí)現(xiàn)最低訪問權(quán)原則。如果程序員不小心修改了這種對象,編譯器會(huì)發(fā)現(xiàn)這種錯(cuò)誤,從而避免運(yùn)行時(shí)的錯(cuò)誤。盡管有的編譯器允許下列錯(cuò)誤存在,但考慮到數(shù)據(jù)封裝的因素,在設(shè)計(jì)程序時(shí)應(yīng)盡量避免下列錯(cuò)誤:(1)定義一個(gè)const成員函數(shù),但該函數(shù)又修改了對象的數(shù)據(jù)成員;(2)定義一個(gè)const成員函數(shù),但該函數(shù)又調(diào)用了非const函數(shù);(3)const對象調(diào)用非const成員函數(shù);(4)試圖修改const對象。

const函數(shù)的聲明或定義規(guī)定必須使用關(guān)鍵字const,該關(guān)鍵字插在函數(shù)參數(shù)列表之后。例如,如下的成員函數(shù)被聲明為const成員函數(shù),它僅僅返回對象的一個(gè)數(shù)據(jù)成員的值:

intgetVuale()const{returnprivateDataMember;}如果在類的定義外部定義const成員函數(shù),那么該成員函數(shù)的定義也必須包含關(guān)鍵字const。

可以把非const成員函數(shù)重載為const成員函數(shù)。編譯器根據(jù)對象在聲明時(shí)是否使用了const來自動(dòng)確定調(diào)用哪一個(gè)重載函數(shù)。由于為了能夠正確地初始化對象,構(gòu)造函數(shù)必須允許修改對象,析構(gòu)函數(shù)也必須要能夠做一些撤銷對象前的清理工作,因此,const對象的構(gòu)造函數(shù)和析構(gòu)函數(shù)不要用關(guān)鍵字const聲明。例3.20把不修改對象值的成員函數(shù)都聲明成const。classTime{public:Time(int=0,int=0,int=0);//默認(rèn)構(gòu)造函數(shù)//"set"函數(shù)voidsetTime(int,int,int); //設(shè)置時(shí)間voidsetHour(int); //設(shè)置hour的值voidsetMinute(int); //設(shè)置minute的值voidsetSecond(int); //設(shè)置second的值//"get"函數(shù)intgetHour()const;//返回hour的值intgetMinute()const; //返回minute的值intgetSecond()const;//返回second的值//輸出函數(shù)(通常被聲明const成員函數(shù))voidprintMilitary()const; //輸出軍用格式的時(shí)間voidprintStandard()const; //輸出標(biāo)準(zhǔn)格式的時(shí)間private:

inthour;//0—23intminute;//0—59intsecond;//0—59};2.復(fù)合一個(gè)類可以把其他類的對象作為自己的成員,這就叫做復(fù)合。復(fù)合是軟件重用的一種形式。在建立對象的時(shí)候,其構(gòu)造函數(shù)自動(dòng)被調(diào)用。如果一個(gè)對象有多個(gè)成員對象,那么這些成員對象應(yīng)該以它們在該對象中的定義順序建立。但是,在編寫程序的時(shí)候,不應(yīng)該編寫依賴于構(gòu)造函數(shù)調(diào)用順序的代碼。下面的程序用類Employee和Date演示了怎樣把對象變?yōu)槠渌麑ο蟮某蓡T。類Employee包括私有數(shù)據(jù)成員lastName、firstName、birthDate和hireDate。成員birthDate和hireDate是類Date的對象,它們包括私有數(shù)據(jù)成員month、day和year。程序建立了類Employee的一個(gè)對象,初始化并輸出了對象的數(shù)據(jù)成員。注意構(gòu)造函數(shù)頭部的語法形式:

Employee::Emplooyee(char*fname,char*lname,intbmonth,intbday,intbyear,inthmonthinthday,inthyear):birthDate(bmonth,bday,byear),hireDate(hmonth,hday,hyear)

這個(gè)構(gòu)造函數(shù)有8個(gè)參數(shù)(fname,lname,bmonth,bday,byear,hmonth,hday和hyear)。頭部的冒號(hào)用于把成員初始化值和參數(shù)列表分開。初始化值是Employee的構(gòu)造函數(shù)中傳遞給成員構(gòu)造函數(shù)的參數(shù)。因此,bmonth、bday和byear傳遞給了birthDate的構(gòu)造函數(shù),hmonth、hday和hyear傳遞給了hireDate的構(gòu)造函數(shù)。多個(gè)成員初始化值之間是用逗號(hào)分隔的。1)類Date的定義classDate{public:Date(int=9,int=1,int=2003); //默認(rèn)構(gòu)造函數(shù)voidprint()const; //按格式"月/日/年"輸出日期private:intmonth; //1-12intday; //1-31(取決于月份)

intyear;

//任意年//根據(jù)年份和月份測試天數(shù)是否正確的工具函數(shù)

intcheckDay(int);};2)成員對象初始化值的用法//構(gòu)造函數(shù):檢查月份值的正確性//調(diào)用工具函數(shù)checkDay核對天數(shù)的正確性Date::Date(intmn,intdy,intyr){month=( mn>&&mn<=12)?mn:1;//檢驗(yàn)正確性

year=y(tǒng)r; //也可以在這里檢驗(yàn)正確性

day=checkDay(dy) //檢驗(yàn)正確性

cout<<"Dateobjectconstructorfordate";print();cout<<endl;}3)檢驗(yàn)天數(shù)正確性的工具函數(shù)intDate::checkDay(inttestDay){staticintdaysPerMonth[13]={0,31,28,31,30,31,30,31,30,31,30,31};if(month!=2){if(testDay>0&&testDay<=dayPerMonth[month])returntestDay;}else{//檢查是否是閏年intdays=(year%400==0||year%4==0&&year%100!=0)?29:28);if(testDay>&&testDay<=days)returntestDay;}cout<<"Day"<<testDay<<"invalid.Settoday1.\n";retrun1; //在值有誤的情況下讓對象處于穩(wěn)定狀態(tài)}4)以“月/日/年”的形式輸出對象DatevoidDate::print()const{cout<<month<<'/'<<day<<'/'<<year;}5)成員對象初始化值的用法之一classEmployee{public:Employee(char*,char*,int,int,int,int,int,int);voidprint()const;private:

charlastName[25];charfirstName[25];DatebirthDate;DatehireDate;};6)成員對象初始化值的用法之二Employee::Employee(char*fname,char*lname,intbmonth,intbday,intbyear,inthmonth,inthday,inthyear):birthday(bmonth,bday,byear),hireDate(hmonth,hday,hyear){strncpy(firstName,fname,24);firstName[24]='\

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論