




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
2023-11-161C++:面向?qū)ο蟪淌皆O(shè)計(jì)2023-11-162類的誕生類(Class)是面向?qū)ο笏枷胫械囊粋€(gè)重要組成部分。如何在電腦中將“類”表達(dá)出來?在C語言中,當(dāng)定義結(jié)構(gòu)體(struct):structSAMPLE{ intmember1,member2;}var1;以後,就可以使用結(jié)構(gòu)中的成員:intvar=var1.member1*var1.member2;2023-11-163將結(jié)構(gòu)體成員的使用代碼寫成一個(gè)函數(shù),得到:intcaluc(structSAMPLEvar){returnvar.member1*var.member2;}操作結(jié)構(gòu)變數(shù)類的誕生2023-11-164然後,將上面的函數(shù)放入結(jié)構(gòu)體中structSAMPLE{
intcalcu() { returnmember1*member2; } intmember1,member2;};數(shù)據(jù)成員函數(shù)成員類的誕生2023-11-165這樣的結(jié)構(gòu)體就具有了一定的屬性(member1和member2),也具有一定的行為(函數(shù)calcu),它就是“類”的雛形。該結(jié)構(gòu)體的使用方法如下:structSAMPLEvar;var.member1=var.member2=10;inttemp=var.calcu();類的誕生2023-11-1662.1類2023-11-1672.1.1類的定義classCCompanyStaff{//BEGIN
//聲明成員函數(shù)voidSetBasicSal(floatsal);//設(shè)置基本工資
//聲明(定義)數(shù)據(jù)成員intm_iStaffNum;//工作編號(hào)charm_cName[20];//姓名floatm_fRateOfAttend;//出勤率floatm_fBasicSal;//基本工資};//END多了一個(gè)函數(shù)(SetBasicSal),其他都象結(jié)構(gòu)體。struct
class2023-11-168CCompanyStaff類的定義以關(guān)鍵字class開始。其後是類名?!皗}”表示類定義的開始和結(jié)束,最終以分號(hào)結(jié)束。一般在類中只聲明成員函數(shù)的原型,而函數(shù)的實(shí)現(xiàn)(即函數(shù)體的定義)則放在類外完成。“函數(shù)原型”,即只聲明函數(shù)名、參數(shù)類型和返回值類型,而不包括函數(shù)體代碼。2.1.1類的定義2023-11-169函數(shù)的定義則可在函數(shù)(SetBasicSal)聲明之後:voidCCompanyStaff::SetBasicSal(floatsal){m_fBasicSal=sal;}函數(shù)定義:函數(shù)名前多了一個(gè)類作用域運(yùn)算符(CCompanyStaff::),用於標(biāo)識(shí)該函數(shù)定義屬於哪一個(gè)類。2.1.1類的定義2023-11-1610對(duì)於C++語言的編程習(xí)慣:1、將類的聲明存放於“*.h”或“*.hpp”的頭檔中,每個(gè)類一個(gè)聲明檔。2、將類的定義存放於“*.cpp”檔中,與相應(yīng)的聲明檔一一對(duì)應(yīng).c
.cpp2.1.1類的定義2023-11-1611封裝成類的好處——可以實(shí)現(xiàn)數(shù)據(jù)隱藏。封裝也確定了類成員的訪問屬性。對(duì)象的封裝性2023-11-1612對(duì)象的封裝性C++語言引入面向?qū)ο笏枷?,引入類(?duì)象)的概念之後,必然會(huì)具有一些新的特性。面向?qū)ο笏枷胫蓄悾▽?duì)象)的基本特性之一:封裝性。封裝性:直觀理解,類將屬於它的數(shù)據(jù)(成員變數(shù))和針對(duì)數(shù)據(jù)的操作(成員函數(shù))包裹在一起就是一種封裝。封裝的目的:保護(hù)類(對(duì)象)的實(shí)現(xiàn)。對(duì)封裝屬性進(jìn)行細(xì)分:公有的;私有的;保護(hù)的。2023-11-1613C++語言為了實(shí)現(xiàn)面向?qū)ο蟮姆庋b,引入了三個(gè)新的“修飾”關(guān)鍵字:public
(公有的):公開的,可見的。對(duì)象成員(變數(shù)與方法)可以在對(duì)象外使用。private
(私有的):不可見的。成員只能在對(duì)象內(nèi)部使用。protected
(保護(hù)的):受到保護(hù)的。成員也只能在內(nèi)部使用。(以後再討論)C++類的成員(變數(shù)和方法)具有了各自不同的屬性。對(duì)象的封裝性2023-11-1614classCCompanyStaff{public:voidSetBasicSal(floatsal);//設(shè)置基本工資private:intm_iStaffNum;//工作編號(hào)charm_cName[20];//姓名floatm_fRateOfAttend;//出勤率floatm_fBasicSal;//基本工資};//END對(duì)象的封裝性2023-11-1615CCompanyStaffstaff;staff.SetBasicSal(600);//合法的,因?yàn)镾etBasicSal是一個(gè)公開(public)的方法。staff.m_iStaffNum=100;//非法的,因?yàn)閙_iStaffNum是一個(gè)私有(private)的變數(shù)。voidCCompanyStaff::SetBasicSal(floatsal){m_fBasicSal=sal;//SetBasicSal是對(duì)象的成員,所以它的定義中可以訪問m_fBasicSal私有變數(shù)。}對(duì)象的封裝性2023-11-16161、C++類定義中的缺省屬性為私有的(private)。2、每個(gè)修飾符的作用範(fàn):從一個(gè)修飾符開始,直到另外一個(gè)修飾符時(shí)結(jié)束(或類結(jié)束了)。3、C++類中的成員(變數(shù)和方法)都應(yīng)該明確地指明它們各自的屬性。對(duì)象的封裝性2023-11-16172.1.2類成員的訪問許可權(quán)封裝所實(shí)現(xiàn)的數(shù)據(jù)隱藏是面向?qū)ο蟪淌皆O(shè)計(jì)的一個(gè)關(guān)鍵特性——隱藏一個(gè)類的數(shù)據(jù)從而使其他類無法訪問。隱藏由封裝實(shí)現(xiàn),所以隱藏所實(shí)現(xiàn)的類成員的訪問控制權(quán)限也和封裝方法一一對(duì)應(yīng)。對(duì)應(yīng)於封裝,類成員有3種訪問許可權(quán):公有類型(public)、私有類型(private)保護(hù)類型(protected)。2023-11-1618類
私有
公有數(shù)據(jù)或函數(shù)數(shù)據(jù)或函數(shù)無法從類外訪問允許從類外訪問2.1.2類成員的訪問許可權(quán)2023-11-1619公有類型的成員定義了類的介面,由關(guān)鍵字public聲明,在類外只能訪問公有成員。私有類型的訪問許可權(quán)為私有的成員由關(guān)鍵字private聲明,它們只能被類本身的成員函數(shù)訪問,來自類外部的任何訪問都是非法的。保護(hù)類型的成員與私有成員類似,區(qū)別僅在於繼承過程中,保護(hù)類型的成員可以被所在類的派生類成員函數(shù)訪問;而這一點(diǎn)對(duì)於私有成員來說是非法的。2.1.2類成員的訪問許可權(quán)2023-11-1620類的成員函數(shù)可以訪問類的所有成員,沒有任何限制;而類對(duì)象訪問類的成員就要受到訪問控制符的限制。訪問許可權(quán)舉例:sclass2_1_demo.hsmain2_1.cpp類對(duì)象和類的成員函數(shù)對(duì)數(shù)據(jù)成員的訪問許可權(quán)不同。2.1.2類成員的訪問許可權(quán)2023-11-1621外部介面是類外訪問類中私有數(shù)據(jù)的橋樑。聲明時(shí),類中不同訪問許可權(quán)的成員可以按任意順序出現(xiàn)。但依然涉及到一個(gè)編程習(xí)慣問題:“以數(shù)據(jù)為中心”
“以行為為中心”
國際公約。2023-11-1622建議把一個(gè)類的數(shù)據(jù)成員都聲明為私有的訪問許可權(quán)。這樣做有兩個(gè)好處:一是資訊隱藏,即實(shí)現(xiàn)封裝,把類的內(nèi)部實(shí)現(xiàn)和外部表現(xiàn)分開,讓使用者無需瞭解類的實(shí)現(xiàn)細(xì)節(jié);二是數(shù)據(jù)保護(hù),將類的重要資訊保護(hù)起來,以免被其他程式不恰當(dāng)?shù)匦薷摹?.1.2類成員的訪問許可權(quán)2023-11-16232.1.3成員函數(shù)的實(shí)現(xiàn)被隱藏的數(shù)據(jù)可以有成員函數(shù)來訪問,對(duì)數(shù)據(jù)的操作也體現(xiàn)在成員函數(shù)中:成員函數(shù)決定對(duì)象的操作行為。它是程式演算法的實(shí)現(xiàn)部分。它也是對(duì)封裝的數(shù)據(jù)進(jìn)行操作的唯一途徑。它有兩種方式:類外實(shí)現(xiàn)和類內(nèi)實(shí)現(xiàn)。注:數(shù)據(jù)對(duì)成員函數(shù)無法隱藏。2023-11-16241.一般實(shí)現(xiàn)方式類外實(shí)現(xiàn)成員函數(shù)的形式如下:返回值類型類名::成員函數(shù)名(形式參數(shù)表){
函數(shù)體}例2.2企業(yè)員工類的實(shí)現(xiàn)。sclass2_2_companyStaff.hs2_2\sclass2_2_companyStaff.cpps2_2\smain2_2.cpp2023-11-16252.內(nèi)聯(lián)函數(shù)方式內(nèi)聯(lián)函數(shù)是指程式在編譯時(shí)用函數(shù)的代碼替換每一處函數(shù)調(diào)用的地方。內(nèi)聯(lián)的優(yōu)點(diǎn)——以空間換時(shí)間。內(nèi)聯(lián)的兩種方式:系統(tǒng)默認(rèn):代碼在類聲明中
例:sclass2_2_0_companyStaff.h函數(shù)前加關(guān)鍵字inline:inline<函數(shù)返回值類型><函數(shù)名>(<形參表>){<函數(shù)體語句>}
參見例:smain2_3.cpp。2023-11-1626內(nèi)聯(lián)和宏替換宏替換是在編譯前由預(yù)處理程式進(jìn)行預(yù)處理,它只做簡單的字元替換而不涉及語法檢查。而內(nèi)聯(lián)函數(shù)是在編譯時(shí)處理的,編譯程序能識(shí)別內(nèi)聯(lián)函數(shù),對(duì)它進(jìn)行語法檢查。2023-11-16272.2類與對(duì)象類(class):具有相同或相近的性質(zhì)和行為的事物集合。對(duì)象(object):theinstanceofaclass。一個(gè)類的實(shí)例,即類的性質(zhì)(變數(shù))具體化之後成為對(duì)象。一個(gè)對(duì)象是類的一種特殊情況。一個(gè)類會(huì)有很多的對(duì)象,一個(gè)對(duì)象屬於一個(gè)類。它們是一對(duì)多的關(guān)係。2023-11-1628C++中的對(duì)象(一)當(dāng)C++中類的成員變數(shù)被賦與特定的值之後,它即成為一個(gè)C++的對(duì)象。CCompanyStaffstaff;//一個(gè)對(duì)象變數(shù)staff.m_iStafNum=12345;staff.m_cName=“張三”
;staff成為類CCompanyStaff的一個(gè)對(duì)象,它有了一個(gè)工作編號(hào),對(duì)應(yīng)一個(gè)人名。當(dāng)然,還會(huì)有很多其他的對(duì)象,比如staff1、staff2等等2023-11-1629C++中的對(duì)象(二)1、對(duì)象針對(duì)電腦而言,就是代碼中的一個(gè)變數(shù)。2、C++中對(duì)象變數(shù)的使用與C語言中結(jié)構(gòu)體變數(shù)的使用方法一樣。CCompanyStaffstaff1,*pstaff1,staff3[10];staff1.m_iStafNum=11111;pstaffm_iStafNum=22222;staff[0].m_iStafNum=33333;2023-11-1630C++類的對(duì)象化(一)C++中對(duì)象是類的變數(shù),但它不象變數(shù)那麼單純。C++提供一套特殊的機(jī)制實(shí)現(xiàn)類到對(duì)象的轉(zhuǎn)換。classCCompanyStaff{public:
CCompanyStaff();~CCompanyStaff();voidSetBasicSal(floatsal);//設(shè)置基本工資private:intm_iStaffNum;//工作編號(hào)};//END2023-11-1631對(duì)象的創(chuàng)建和銷毀創(chuàng)建對(duì)象時(shí),“對(duì)象存放在何處??”需要向操作系統(tǒng)申請(qǐng)一定的記憶體空間用於存放新建的對(duì)象。為對(duì)象分配存儲(chǔ)空間主要有:靜態(tài)分配和動(dòng)態(tài)分配兩種方式。2023-11-1632靜態(tài)分配:可以將對(duì)象或靜態(tài)成員存放在棧中或靜態(tài)存儲(chǔ)區(qū)域中。動(dòng)態(tài)分配:
動(dòng)態(tài)記憶體分配是指在堆(也稱自由記憶體)中分配存儲(chǔ)單元,即為對(duì)象動(dòng)態(tài)從堆中分配記憶體。使用操作符new分配記憶體空間;使用操作符delete釋放記憶體空間。對(duì)象的創(chuàng)建和銷毀2023-11-16332.1.1構(gòu)造函數(shù)與析構(gòu)函數(shù)C++語言為了保證一個(gè)對(duì)象被初始化(類的實(shí)例化),定義了一組特殊的方法(函數(shù)),專門用於對(duì)象生成時(shí)的初始化。構(gòu)造函數(shù)(constructor)——與類名稱相同,沒有返回值。它在對(duì)象生成之時(shí)自動(dòng)執(zhí)行。析構(gòu)函數(shù)(destructor)——在類名前加~作為函數(shù)名的函數(shù),沒有返回值,也沒有參數(shù)。它在對(duì)象結(jié)束時(shí)自動(dòng)執(zhí)行。2023-11-1634C++要求類設(shè)置一個(gè)專門的成員函數(shù)來負(fù)責(zé)類中所有對(duì)象的初始化,這個(gè)成員函數(shù)就是構(gòu)造函數(shù)。構(gòu)造函數(shù)的作用就是在對(duì)象被創(chuàng)建時(shí)利用特定的值構(gòu)造對(duì)象,將對(duì)象初始化到一個(gè)特定的狀態(tài)。聲明一個(gè)構(gòu)造函數(shù)的語示格式如下:public:類名(<參數(shù)表>);2.1.1構(gòu)造函數(shù)與析構(gòu)函數(shù)2023-11-1635構(gòu)造函數(shù)可以由程式設(shè)計(jì)人員自己編寫。也可以由系統(tǒng)提供。例2.4構(gòu)造函數(shù)舉例。sclass2_4_companyStaff.hsmain2_4.cpp2.1.1構(gòu)造函數(shù)與析構(gòu)函數(shù)2023-11-1636重載構(gòu)造函數(shù)所謂重載構(gòu)造函數(shù),是指同一個(gè)構(gòu)造函數(shù)名,具有不同的實(shí)現(xiàn)。例2.5在員工管理系統(tǒng)中,創(chuàng)建一個(gè)對(duì)象時(shí),還可以一次性地給對(duì)象的姓名、出勤率、基本工資等幾個(gè)數(shù)據(jù)成員都賦初值,這就需要重載構(gòu)造函數(shù)。sclass2_5_companyStaff.hsclass2_5_companyStaff.cppsmain2_5.cpp2023-11-1637需要注意一點(diǎn),當(dāng)構(gòu)造函數(shù)帶默認(rèn)參數(shù)時(shí),要謹(jǐn)防出現(xiàn)歧義。例2.6下麵這個(gè)程式存在歧義。sclass2_6.hsmain2_6.cpp當(dāng)創(chuàng)建對(duì)象d2時(shí),有二義性。2.1.1構(gòu)造函數(shù)與析構(gòu)函數(shù)2023-11-1638拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)是用來複製對(duì)象的一種特殊的構(gòu)造函數(shù)。聲明拷貝構(gòu)造函數(shù)的語法格式如下:class類名{public:
類名(類名&對(duì)象名);};只有一個(gè)參數(shù)2023-11-1639例2.7通過水準(zhǔn)座標(biāo)和垂直座標(biāo)來確定螢?zāi)簧系囊粋€(gè)點(diǎn)。sclass2_7_point.hsmain2_7.cppCPointb(a);CPointc=a;拷貝構(gòu)造函數(shù)2023-11-1640析構(gòu)函數(shù)析構(gòu)函數(shù)與構(gòu)造函數(shù)的作用幾乎正好相反,當(dāng)一個(gè)對(duì)象消失時(shí),或用delete刪除用new創(chuàng)建的對(duì)象時(shí),系統(tǒng)都會(huì)自動(dòng)調(diào)用類的析構(gòu)函數(shù),做一些清理工作。聲明一個(gè)析構(gòu)函數(shù)的語法格式如下:classDemo{public: Demo(<參數(shù)表>); ~Demo(void);}2023-11-1641析構(gòu)函數(shù)不能重載。
//析構(gòu)函數(shù)
~CCompanyStaff(void) { cout<<"對(duì)象"<<m_cName<<"消亡"<<endl; }析構(gòu)函數(shù)2023-11-1642當(dāng)某對(duì)象消亡時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用該對(duì)象的析構(gòu)函數(shù)。而且調(diào)用的順序是:最後創(chuàng)建的對(duì)象最先消亡,即最先調(diào)用其析構(gòu)函數(shù);相反地,最先創(chuàng)建的對(duì)象最後消亡,即最後調(diào)用其析構(gòu)函數(shù)。 如果不顯式地定義析構(gòu)函數(shù),系統(tǒng)也會(huì)生成一個(gè)默認(rèn)的析構(gòu)函數(shù),它是一個(gè)空的析構(gòu)函數(shù),不做任何事情。析構(gòu)函數(shù)2023-11-1643C++類的對(duì)象化(附)classCCompanyStaff{public:
CCompanyStaff();CCompanyStaff(intnum,char*pName);~CCompanyStaff();voidSetBasicSal(floatsal);//設(shè)置基本工資……………};//ENDCCompanyStaffstaff(12345,“張三”);2023-11-1644C++類的對(duì)象化(附)1、構(gòu)造函數(shù)與析構(gòu)函數(shù)被“隱含”調(diào)用,即不管願(yuàn)意與否,它們都會(huì)被“強(qiáng)制”地執(zhí)行。2、C++類都有缺省的構(gòu)造函數(shù),即沒有參數(shù)的構(gòu)造函數(shù)。它也是“強(qiáng)制”的,沒有定義每個(gè)類也有一個(gè)這樣的構(gòu)造函數(shù)。3、編程習(xí)慣:不管有用沒用,希望編程人員為每個(gè)類定義明確的構(gòu)造與析構(gòu)函數(shù)2023-11-16452.2.3對(duì)象成員的訪問可以通過對(duì)象名,也可以通過對(duì)象地址來訪問一個(gè)對(duì)象:<類名><對(duì)象名>; <對(duì)象名>.<成員名> //訪問公有數(shù)據(jù)成員<對(duì)象名>.<成員名>(<參數(shù)表>)
//訪問公有成員函數(shù)CCompanyStaffstaff1("LiHua"); staff1.SetBasicSal(4000.0);2023-11-1646<類名>*<對(duì)象指針名>;<對(duì)象指針>-><成員名> //訪問公有數(shù)據(jù)成員<對(duì)象指針>-><成員名>(<參數(shù)表>)
//訪問公有成員函數(shù)CCompanyStaff*pstaff;pstaff=newCCompanyStaff("LiuMei",0.95,3000.0);pstaff->GetName()
2.2.3對(duì)象成員的訪問2023-11-1647例2.8在員工管理系統(tǒng)中,建立兩個(gè)對(duì)象分別用兩種方式去訪問類成員。sclass2_8_companyStaff.hsclass2_8_companyStaff.cppsmain2_8.cpp2.2.3對(duì)象成員的訪問2023-11-1648對(duì)象指針:普通對(duì)象指針例2.9普通對(duì)象指針舉例。sclass2_9_objPointer.hsmain2_9.cpp
CPointerExam*pointer; pointer=&obj;
pointer->SetNum(2);對(duì)象指針在使用之前一定要初始化,為其動(dòng)態(tài)分配存儲(chǔ)空間;使用完畢必須釋放該對(duì)象指針?biāo)淼馁Y源。2023-11-1649對(duì)象的this指針每個(gè)對(duì)象都擁有自己獨(dú)立的數(shù)據(jù)成員。而類中的所有對(duì)象使用相同的成員函數(shù),成員函數(shù)在內(nèi)存中只有一份。每個(gè)對(duì)象隱含了一個(gè)常量指針,稱為this指針,用於指向當(dāng)前發(fā)送消息的對(duì)象,以識(shí)別當(dāng)前調(diào)用成員函數(shù)的對(duì)象究竟是誰。當(dāng)通過一個(gè)對(duì)象調(diào)用成員函數(shù)時(shí),系統(tǒng)先將該對(duì)象的地址賦給this指針,成員函數(shù)在對(duì)對(duì)象的數(shù)據(jù)進(jìn)行操作時(shí),就隱含地使用了this指針。2023-11-1650CCompanyStaff(charcName[]) {
strcpy(m_cName,cName);}CCompanyStaff(charcName[],CCompanyStaff*constthis) {
strcpy(this->m_cName,cName);
}顯示指明this對(duì)象的this指針2023-11-1651CCompanyStaff(charcName[]) {
strcpy(this->m_cName,cName);
}隱含this對(duì)象的this指針2023-11-1652一般不需要顯示指出this,只有當(dāng)函數(shù)需要返回當(dāng)前對(duì)象自身的時(shí)候,才顯式地使用它。例2.10this指針舉例。sclass2_10_this.hsmain2_10.cpp
CSampleAdd(CSamples1,Csamples2) { this->n=s1.n+s2.n;
return(*this); }對(duì)象的this指針2023-11-1653類成員指針(1)類數(shù)據(jù)成員指針如果指針指向類數(shù)據(jù)成員的地址,則這個(gè)指針稱為類數(shù)據(jù)成員指針;<類型><類名>::*<指針名>
sclass2_11_dataPointer.hsmain2_11.cpp
intCSample::*p=&CSample::m; CSamples1; s1.*p=20;類數(shù)據(jù)成員指針只能指向公有數(shù)據(jù)成員。2023-11-1654(2)類成員函數(shù)指針如果指針指向類成員函數(shù)的地址,則稱為類成員函數(shù)指針。聲明一個(gè)類成員函數(shù)指針並為其賦值的語法格式如下:<類型>(<類名>::*<指針名>)(<參數(shù)表>)
<指針名>=<類名>::<成員函數(shù)名>;
使用指向成員函數(shù)的指針調(diào)用函數(shù)的格式如下:(*<指針名>)(<實(shí)參表>)
類成員指針2023-11-1655//主文件:smain2_12.cpp#include"sclass2_8_companyStaff.h"
//包含sclass2_8_companyStaff.h的代碼#include<iostream>usingnamespacestd;voidmain(void){ void(CCompanyStaff::*pFunc)(float);
//聲明一個(gè)類成員函數(shù)指針
CCompanyStaffstaff("LiHua");
//創(chuàng)建一個(gè)對(duì)象staff pFunc=CCompanyStaff::SetBasicSal;//指針初始化指向SetBasicSal函數(shù)
(staff.*pFunc)(3000);//相當(dāng)於staff調(diào)用SetBasicSal() cout<<"員工LiHua的基本工資是"<<staff.GetBasicSal();}類成員指針2023-11-1656對(duì)象數(shù)組例2.13對(duì)象數(shù)組應(yīng)用舉例sclass2_13_fruit.hsmain2_13.cpp
CFruitd[4];
//創(chuàng)建一個(gè)對(duì)象數(shù)組,相應(yīng)調(diào)用4次構(gòu)造函數(shù)如需要建立一個(gè)對(duì)象數(shù)組,必須滿足以下條件:至少有一個(gè)構(gòu)造函數(shù)沒有參數(shù)或只帶默認(rèn)參數(shù)。2023-11-1657Static靜態(tài)成員static(靜態(tài))修改類中的成員(變數(shù)和函數(shù)),表明該成員只有一個(gè)副本,與具體的對(duì)象沒有關(guān)係。static後的成員變數(shù)可以用於對(duì)象間的數(shù)據(jù)共用。static後的成員函數(shù)只能使用static成員變數(shù)。2023-11-1658static成員的使用當(dāng)一個(gè)成員被static修飾之後,它的使用不再屬於各個(gè)對(duì)象,而是屬於這個(gè)類。classCCompanyStaff{public:staticvoidSetBasicSal(floatsal);
intm_iStaffNum;};//ENDCCompany::m_iStaffNum=1234;CCompany::SetBasicSal(30000);2023-11-1659靜態(tài)成員類的靜態(tài)成員擁有一塊單獨(dú)的存儲(chǔ)區(qū)。該類的所有對(duì)象都共用這塊靜態(tài)存儲(chǔ)空間這就為對(duì)象提供了一個(gè)相互通信的方法。靜態(tài)成員由關(guān)鍵字static標(biāo)識(shí)。它屬於類而不屬於對(duì)象。它分為靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù)。2023-11-1660聲明一個(gè)靜態(tài)數(shù)據(jù)成員的語法格式如下:static<數(shù)據(jù)類型><靜態(tài)數(shù)據(jù)成員名>靜態(tài)數(shù)據(jù)成員在使用前也要初始化,但它的初始化不能在構(gòu)造函數(shù)中進(jìn)行,在類外進(jìn)行。<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=〈初始值〉;其訪問語法格式如下:<類名>::<靜態(tài)數(shù)據(jù)成員名>靜態(tài)成員2023-11-1661sclass2_14_companyStaff.hsclass2_14_companyStaff.cppsmain2_14.cpp
staticints_iCount;intCCompanyStaff::s_iCount=1000;靜態(tài)成員2023-11-1662靜態(tài)成員函數(shù)是一種特殊的成員函數(shù),它屬於整個(gè)類,也為同類中所有對(duì)象共同擁有。只要類存在,靜態(tài)成員函數(shù)就可以使用??梢酝ㄟ^類名和對(duì)象名來調(diào)用。其定義語法格式如下:<類名>::<靜態(tài)成員函數(shù)名>(<參數(shù)表>)例2.15靜態(tài)成員函數(shù)舉例。sclass2_15.hsmain2_15.cpp靜態(tài)成員2023-11-1663靜態(tài)成員函數(shù)一般不訪問普通數(shù)據(jù)成員,它的作用主要是訪問和操作同類中的靜態(tài)數(shù)據(jù)成員。類的普通成員函數(shù)都擁有this指針。而靜態(tài)成員函數(shù)沒有this指針,但可以通過類名或?qū)ο竺麃韺?shí)現(xiàn)對(duì)它的訪問。靜態(tài)成員2023-11-1664對(duì)象封裝性的局限已經(jīng)學(xué)習(xí)過類對(duì)於成員的封裝(public,private,protected)封裝性有效地保護(hù)了對(duì)象的內(nèi)部細(xì)節(jié),使得對(duì)象的使用和對(duì)象的實(shí)現(xiàn)分開,互相不產(chǎn)生影響。同時(shí),封裝性帶來負(fù)面影響:1、C++為實(shí)現(xiàn)對(duì)象的封裝,必然會(huì)做一些額外的工作,從而導(dǎo)致程式的效率下降。2、一個(gè)對(duì)象封裝的太好,也會(huì)讓該對(duì)象很難使用,也很難實(shí)現(xiàn)。2023-11-1665突破對(duì)象封裝C++提供了友元(friend)來解決由封裝性帶來的問題。friend關(guān)鍵字修改函數(shù)或類,因此對(duì)於一個(gè)類而言,它有友元函數(shù)或友元類。friend用於應(yīng)對(duì)編程中一些比較特殊的情況(如提高效率),絕大多數(shù)情況下不需要使用。亂使用只會(huì)使C++變成C,甚至更糟。2023-11-16665.友元關(guān)係一個(gè)類可以聲明一個(gè)友元關(guān)係,一起來共用類中的所有成員。友元如果是一個(gè)函數(shù),則稱為友元函數(shù);如果是一個(gè)類,則稱為友元類。友元函數(shù)是在類中由關(guān)鍵字friend修飾的非成員函數(shù)。友元函數(shù)可以是一個(gè)普通的函數(shù),也可以是其他類的成員函數(shù)。雖然它不是本類的成員函數(shù),但是在它的函數(shù)體中可以通過對(duì)象名訪問類的私有和保護(hù)成員。2023-11-1667例2.16友元函數(shù)與成員函數(shù)的比較。sclass2_16.hsmain2_16.cpp(例中的友元關(guān)係會(huì)發(fā)生錯(cuò)誤)friendvoidFriendFunc(CSample*cp,inta)//增加一個(gè)對(duì)象指針參數(shù){ cp->i=a;//對(duì)象指針參數(shù)為i指明當(dāng)前所屬對(duì)象}需要操作對(duì)象5.友元關(guān)係2023-11-1668友元函數(shù)的特點(diǎn):第一、友元函數(shù)可以直接訪問該類的所有成員,但它不是該類的成員函數(shù),可以像普通函數(shù)一樣在任何地方調(diào)用。第二、友元函數(shù)不屬於任何類,因此可以放在類說明的任何位置,既可以在public區(qū),也可以在private區(qū)。第三、友元函數(shù)不需要通過對(duì)象或?qū)ο笾羔榿碚{(diào)用,可以直接調(diào)用即可。5.友元關(guān)係2023-11-1669友元類在類中可把另一個(gè)類聲明為友元類,如類B是類A的友元類,則類B中的所有成員函數(shù)都是類A的友元函數(shù),都可以訪問類A的私有和保護(hù)成員。友元類的聲明語句如下:classB;//前向引用聲明classA{ …… friendclassB;//B為A的友元類
……}5.友元關(guān)係2023-11-1670例2.17編寫一個(gè)有關(guān)棧結(jié)構(gòu)的程式,要求實(shí)現(xiàn)入棧和出棧。其中有兩個(gè)類,一個(gè)是結(jié)點(diǎn)類CNode,擁有結(jié)點(diǎn)值和指向下一結(jié)點(diǎn)的指針;另一個(gè)是棧類CStack,它擁有棧的頭指針。由此生成的鏈?zhǔn)浇Y(jié)構(gòu)如圖2.3所示。321頭指針棧頂棧底指向下一結(jié)點(diǎn)的指針5.友元關(guān)係2023-11-1671sclass2_17_stack.hsclass2_17_stack.cppsmain2_17由於棧類CStack是結(jié)點(diǎn)類CNode的友元類,所以棧CStack類的所有成員函數(shù)都成為類CNode的友元函數(shù)。因此Push()和Pop()可以訪問結(jié)點(diǎn)類CNode對(duì)象的私有成員並對(duì)其進(jìn)行操作。封裝是對(duì)象與外界之間一堵不透明的牆,而友元恰好在這堵牆上開了一個(gè)小孔,它以犧牲資訊隱藏、削弱封裝性為代價(jià)來實(shí)現(xiàn)數(shù)據(jù)共用。5.友元關(guān)係2023-11-16722.3C++輸入輸出流對(duì)象標(biāo)準(zhǔn)輸入輸出流:數(shù)據(jù)從程式中流入到螢?zāi)换虼牌瑱n,即輸出流;數(shù)據(jù)從鍵盤流入到程式中,即輸入流。所謂流,是從源到矢的數(shù)據(jù)流的抽象引用,具體地說,就是數(shù)據(jù)從一個(gè)對(duì)象流向另一個(gè)對(duì)象。在進(jìn)行I/O操作時(shí),首先執(zhí)行打開操作,使流和文件發(fā)生聯(lián)繫,建立聯(lián)繫後的檔才允許數(shù)據(jù)流入或流出,輸入輸出結(jié)束後,執(zhí)行關(guān)閉操作使檔與流斷開聯(lián)繫。2023-11-16732.2.1標(biāo)準(zhǔn)輸入輸出流iosistreamostreamifstreamiostreamofstreamstreambuffilebufstringbuffstreambaseistream_withassignostream_withassigniostream_withassignfstreamC++流類庫C++提供了一個(gè)流類庫,它具有兩個(gè)平行的根基類:streambuf類和ios類。2023-11-1674streambuf類主要負(fù)責(zé)緩衝區(qū)的處理,提供對(duì)緩衝區(qū)的低級(jí)操作。ios類是流基類,它及其派生類提供用戶使用流類所需的介面,支持對(duì)streambuf的緩衝。由它可以派生出輸入流類istream和輸出流類ostream等。兩個(gè)根基類以及由它們派生出的所有流類(當(dāng)然包括istream類和ostream類)都被定義在名為iostream的頭檔中。因此須用“#include”編譯指令將iostream頭檔包含進(jìn)來。C++流類庫2023-11-16752023-11-1676系統(tǒng)預(yù)定義的一些流:進(jìn)行輸入輸出常用的標(biāo)準(zhǔn)輸入流對(duì)象cin和標(biāo)準(zhǔn)輸出流對(duì)象cout,還有未被緩衝的標(biāo)準(zhǔn)錯(cuò)誤輸出cerr和被緩衝的標(biāo)準(zhǔn)錯(cuò)誤輸出clog。2.預(yù)定義輸入/輸出流cin和cout2023-11-1677cin是通用輸入流類istream_withassign的對(duì)象,與標(biāo)準(zhǔn)輸入設(shè)備連接。它通過重載運(yùn)算符“>>”執(zhí)行輸入操作,在流操作中將“>>”稱為提取運(yùn)算符。cin從輸入流中取出數(shù)據(jù),數(shù)據(jù)從提取運(yùn)算符“>>”處流進(jìn)程序。2.預(yù)定義輸入/輸出流cin和cout2023-11-1678cout是通用輸出流類ostream的對(duì)象,與標(biāo)準(zhǔn)輸出設(shè)備連接。通過重載運(yùn)算符“<<”執(zhí)行輸出操作,在流操作中,將“<<”稱為插入運(yùn)算符。插入運(yùn)算符“<<”向輸出流發(fā)送字元。實(shí)際上,位於插入運(yùn)算符右側(cè)的字串被存儲(chǔ)在“<<”左側(cè)的流中。cout<<m<<""<<n<<endl;cout<<m;cout<<“
“;cout<<n;cout<<endl;2.預(yù)定義輸入/輸出流cin和cout2023-11-1679預(yù)定義操縱符操縱符是直接插入到流中的格式化指令,一般都定義在ios_base類中和<iomanip>頭檔中,分為帶參數(shù)和不帶參數(shù)兩類。2023-11-16802.預(yù)定義輸入/輸出流cin和cout例如:cout<<setw(5)<<n<<endl;表示設(shè)置輸出n時(shí)所占的位元組長度為5,輸出n後換行。2023-11-16812.3.2檔輸入輸出流輸入是指從磁片檔流向記憶體。輸出是指從記憶體流向磁片。
C++提供了3個(gè)檔流類:ofstream,ifstream,fstream,都定義在頭檔fstream.h中。其中fstream類以ofstream類和ifstream類為基類。ofstream類:輸出流類,用於向檔中寫入內(nèi)容;ifstream類:輸入流類,用於從檔中讀出內(nèi)容;fstream類:輸入輸出流類,用於既要讀又要寫的檔操作。2023-11-1682ofstream::ofstream(char*pFileName,intmode=ios::out,intprof=filebuf::openprot);第一個(gè)參數(shù)用於指業(yè)檔路徑及檔案名字串,第二個(gè)參數(shù)說明文件打開方式,第三個(gè)參數(shù)說明文件保護(hù)方式。例2.18給出程式的執(zhí)行結(jié)果smain2_18.cpp檔流對(duì)象構(gòu)造函數(shù)2.3.2檔輸入輸出流2023-11-16832.3.2檔輸入輸出流2023-11-16842.3.2檔輸入輸出流2023-11-1685(1)輸入流成員函數(shù)
open()close()get()getline()read()(2)輸出流成員函數(shù)put()write()2.常用輸入輸出流成員函數(shù)2023-11-16862.常用輸入輸出流成員函數(shù)例2.19下麵的程式將用戶輸入顯示到螢?zāi)簧?,輸入字母y時(shí)輸出OK並結(jié)束。smain2_19.cpp
例2.20連續(xù)讀入一串字元,直到遇到字元q時(shí)停止,然後輸出這個(gè)字串。要求字元個(gè)數(shù)最多不超過79個(gè)。smain2_20.cpp
例2.21將英文字母及對(duì)應(yīng)的ASCⅡ值輸出到螢?zāi)簧?。smain2_21.cpp
2023-11-1687C++流的應(yīng)用1、C++專門為互動(dòng)式輸入與輸出定義了兩個(gè)對(duì)象:cin用於鍵盤的輸入;cout用於顯示幕的輸出。2、所有的C++流都有兩個(gè)操作符<<
和>><<:輸出(插入)操作符。流對(duì)象<<數(shù)據(jù);>>:輸入(提?。┎僮鞣?。流對(duì)象>>數(shù)據(jù);2023-11-1688輸入輸出流應(yīng)用舉例例2.22員工管理系統(tǒng)中的輸入輸出sclass2_22_companyStaff.hsclass2_22_companyStaff.cppsmain2_22.cpp2023-11-1689習(xí)題課後習(xí)題、作業(yè)習(xí)題1習(xí)題2習(xí)題42023-11-1690Thanks!TheEnd2023-11-1691派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù)第三章繼承132繼承方式類的繼承與派生4虛基類5聚合類6繼承應(yīng)用實(shí)例本章內(nèi)容2023-11-1692
3.1類的繼承與派生3.1.1繼承與派生實(shí)例繼承是軟體重用的一種形式。繼承是將自然界中存在的普遍和特殊關(guān)係用程式設(shè)計(jì)的方式進(jìn)行分類描述;在設(shè)計(jì)新類時(shí),允許重用某個(gè)原有類的所有特徵,並在此基礎(chǔ)上添加新類的新特徵。被重用的原有類稱為基類baseclass而新創(chuàng)建的類稱為派生類derivedclass。派生類不會(huì)影響到原有類的結(jié)構(gòu)。2023-11-1693實(shí)例:某一小型公司的實(shí)例企業(yè)員工工作編號(hào)姓名……顯示企業(yè)員工資訊計(jì)算實(shí)際發(fā)放工資……行政人員(與企業(yè)員工類相同)計(jì)算實(shí)際發(fā)放工資……經(jīng)理公司總銷售額提成比例(其餘同企業(yè)員工類)計(jì)算實(shí)際發(fā)放工資……銷售人員個(gè)人銷售額提成比例(其餘同企業(yè)員工類)計(jì)算實(shí)際發(fā)放工資……2023-11-16943.1類的繼承與派生針對(duì)該公司的情況,先設(shè)計(jì):一個(gè)一般員工類CCompanyStaff,代表員工的共性;讓三個(gè)新類分別繼承一般員工類CCompanyStaff,然後根據(jù)各自的差異性,新類可以對(duì)繼承來的內(nèi)容進(jìn)行改造。2023-11-16953.1.2派生類的定義從已有類產(chǎn)生新類的過程就是類的派生。定義語法如下:
class<派生類名><繼承方式>:<基類名1>, <繼承方式>:<基類名2>…{ <派生類成員的定義>; }3.1類的繼承與派生2023-11-1696繼承方式分為三種關(guān)鍵字:publicprivate
protected;單繼承(只有一個(gè)基類名)和多繼承;該公司情況類代碼:企業(yè)員工類相關(guān)派生類P79經(jīng)理、銷售人員、行政人員這三個(gè)派生類在聲明語句中分別指定了它們的基類CCompanyStaff,以及它們的繼承方式-public;CSaleManager類,同時(shí)繼承經(jīng)理類Cmanager和銷售人員類Csaleman;3.1類的繼承與派生2023-11-1697銷售員經(jīng)理行政主管行政人員企業(yè)員工類圖3.1.3繼承的級(jí)別增加行政主管一職,員工關(guān)係圖如下:3.1類的繼承與派生2023-11-1698用C++語言描述三個(gè)類的前向引用聲明,形成了一個(gè)“類家族”:classCCompanyStaff;//基類員工//派生類行政人員繼承員工classCAdminStaff:publicCCompanyStaff;
//派生類行政主管繼承行政人員classCForeAdmin:publicCAdminStaff;基類不受派生類變化的影響;派生類繼承了基類的全部數(shù)據(jù)成員和除了構(gòu)造函數(shù)析構(gòu)函數(shù)之外的全部成員函數(shù),但是派生類能否訪問這些成員還要受繼承方式的約束;3.1類的繼承與派生2023-11-16993.2繼承方式3.2.1公有繼承類的繼承方式有public、private和protected三種,其中private是缺省的繼承方式;公有繼承:
基類各成員的訪問許可權(quán)如果是public或protected則在派生類中保持不變而基類中的private成員對(duì)派生類不可見,如圖:2023-11-16100private基類Base圖3.3公有繼承中的訪問控制protectedpublicprivate派生類Derv:publicBaseprotectedpublicDervobjDBaseobjB3.2繼承方式2023-11-16101
例3.1一個(gè)公有繼承的例子:sclass3_1.hsclass3_1.cppsmain3_1.cpp
基類A的所有成員在派生類中的訪問控制權(quán)限都保持不變。3.2繼承方式2023-11-161023.2.2私有繼承:基類各成員無論是何種訪問許可權(quán)在派生類中一律以private的身份出現(xiàn),連派生類的對(duì)象也無法訪問,只有派生類的函數(shù)能在類內(nèi)訪問它們。若要私有繼承來的某些基類的成員函數(shù)在派生類中也能對(duì)外可見,需在派生類中對(duì)其成員公有化。
usingCAnimal::SetWeight;//在派生類中將基類的成員函數(shù)SetWeight()公有化
usingCAnimal::GetWeight;//在派生類中將基類的成員函數(shù)GetWeight()公有化例3.2私有繼承中的公有化:sclass3_2.hsmain3_2.cpp3.2繼承方式2023-11-16103私有繼承後的基類成員成為了派生類的私有成員,實(shí)際上相當(dāng)於終止了基類功能的繼續(xù)派生。class<派生類名>:private<基類名>{public:
using<基類名>::<基類函數(shù)名>;//公有化
……};3.2繼承方式2023-11-161043.2.3保護(hù)繼承:
protected訪問許可權(quán): 設(shè)計(jì)基類時(shí),在隱藏成員的同時(shí)還要允許派生類的成員能訪問到,這時(shí)protected就比private更合適;
例3.3保護(hù)許可權(quán)舉例:sclass3_3.hsmain3_3.cpp3.2繼承方式2023-11-16105使用protected修飾類成員存在的隱患,它破壞了封裝;
protected繼承;
保護(hù)繼承下基類各成員的訪問許可權(quán)(除private外)都以protected許可權(quán)出現(xiàn);比較私有繼承和保護(hù)繼承,可以看出在直接派生類中兩者的效果實(shí)際上都相同,但如果再繼續(xù)派生下去就會(huì)出現(xiàn)區(qū)別;3.2繼承方式2023-11-16106假設(shè)有A<-B<-C這樣一個(gè)繼承順序如果B私有繼承A後又派生出C那麼C就無法再間接繼承A的成員對(duì)A功能的繼承在B那兒就終止了;而如果B保護(hù)繼承A後又派生出C那麼A中的公有和保護(hù)成員在B中都是保護(hù)成員因此A的功能可以被C間接繼承;在實(shí)際開發(fā)時(shí)選擇恰當(dāng)?shù)睦^承方式;3.2繼承方式2023-11-161073.2繼承方式3.2.4多繼承(多個(gè)父類):聲明多繼承的語法如下:
class<派生類名>:<繼承方式><基類名1>,<繼承方式><基類名2>,…多繼承舉例:在公司員工管理中有時(shí)會(huì)存在多繼承關(guān)係,如圖:經(jīng)理銷售部經(jīng)理銷售人員2023-11-161083.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)3.3.1構(gòu)造函數(shù):在創(chuàng)建派生類的對(duì)象時(shí),系統(tǒng)執(zhí)行派生類的構(gòu)造函數(shù)而不會(huì)自動(dòng)執(zhí)行基類的構(gòu)造函數(shù);在設(shè)計(jì)派生類的構(gòu)造函數(shù)時(shí),不僅要為初始化派生類新增加的數(shù)據(jù)提供參數(shù),而且還應(yīng)為初始化基類數(shù)據(jù)成員提供參數(shù)相關(guān)語法:
<派生類名>(<形參表>):<基類名1>(<形參表1>)<基類名2>(<形參表2>)
{ <派生類新增數(shù)據(jù)成員的初始化> }2023-11-161093.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類構(gòu)造函數(shù)的調(diào)用順序?yàn)橄雀篙?基類數(shù)據(jù))後自己(派生類新數(shù)據(jù));轎車具有交通工具的一般特徵,比如輪胎數(shù)目,同時(shí)又具有轎車自身的特徵,如載客人數(shù),因此轎車?yán)^承交通工具,成為它的一個(gè)派生類。例3.4派生類構(gòu)造函數(shù)舉例:sclass3_4.hsmain3_4.cpp2023-11-161103.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類必須定義構(gòu)造函數(shù)的兩種情況:派生類新增的數(shù)據(jù)成員需要定義構(gòu)造函數(shù)來為其初始化;基類定義了帶參數(shù)的構(gòu)造函數(shù)需要派生類為其提供參數(shù)以完成基類數(shù)據(jù)成員的初始化。2023-11-161113.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)3.3.2析構(gòu)函數(shù)當(dāng)派生類對(duì)象消亡時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用派生類的析構(gòu)函數(shù)做一些必要的清理工作;由於在繼承過程中派生類不能繼承基類的析構(gòu)函數(shù),所以如果需要就只能在派生類中重新定義;2023-11-16112在執(zhí)行派生類的析構(gòu)函數(shù)時(shí)基類的析構(gòu)函數(shù)也將被自動(dòng)調(diào)用;析構(gòu)函數(shù)調(diào)用的順序是先派生類的析構(gòu)函數(shù),然後是基類的析構(gòu)函數(shù)。例3.5派生類析構(gòu)函數(shù)舉例:
sclass3_5.hsmain3_5.cpp3.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)調(diào)用類A的構(gòu)造函數(shù)調(diào)用類B的構(gòu)造函數(shù)調(diào)用類B的析構(gòu)函數(shù)調(diào)用類A的析構(gòu)函數(shù)2023-11-161133.4虛基類3.4.1聲明一個(gè)虛基類
多繼承中的多義性
2023-11-161142.作用域分辨符可以通過作用域分辨符明確指定調(diào)用哪個(gè)類的介面;其語法形式如下:<派生類對(duì)象名>.<基類名>::<數(shù)據(jù)成員名>//訪問數(shù)據(jù)成員<派生類對(duì)象名>.<基類名>::<成員函數(shù)名><參數(shù)表>//訪問成員函數(shù)3.4虛基類2023-11-16115作用域分辨符舉例:Smain3_5_B.cpp基類可以將其設(shè)為虛基類,這樣它的數(shù)據(jù)成員在內(nèi)存中就只有一個(gè)副本,成員函數(shù)也只有一個(gè)映射從而解決了同名成員的唯一標(biāo)識(shí)問題;3.4虛基類2023-11-161163.虛基類由virtual標(biāo)識(shí),聲明語法如下:class<派生類名>:virtual<繼承方式><基類名>;例3.6虛基類舉例:sclass3_6.hsmain3_6.cpp考慮員工管理系統(tǒng)中的多繼承關(guān)係使用虛基類來定義公司員工管理系統(tǒng)中的多繼承關(guān)係:3.4虛基類2023-11-16117//在繼承路徑“銷售經(jīng)理—>銷售人員—>員工”中將基類CCompanyStaff設(shè)為虛基類classCSaleman:virtualpublicCCompanyStaff;//在繼承路徑“銷售經(jīng)理—>經(jīng)理—>員工”中將基類CCompanyStaff設(shè)為虛基類classCManager:virtualpublicCCompanyStaff;//派生類CSaleManager成為兩條繼承路徑的交匯點(diǎn)classCSaleManager:publicCSaleman,publicCmanager;3.4虛基類2023-11-16118比較使用作用域分辨符和虛基類技術(shù):使用作用域分辨符時(shí)基類的成員在內(nèi)存中存在多個(gè)副本,通過指定基類名來唯一標(biāo)識(shí)使用的是哪個(gè)副本,這樣可以存放不同的數(shù)據(jù)進(jìn)行不同的操作;使用虛基類技術(shù)使基類的成員在內(nèi)存中只存有一個(gè)副本;3.4虛基類2023-11-161193.4.2虛基類的初始化:虛基類的初始化在語法上和處理一般基類一樣只是調(diào)用順序略有不同它遵循以下順序:1)虛基類的構(gòu)造函數(shù)在非虛基類之前調(diào)用;2)若同一層次中包含多個(gè)虛基類則按它們的聲明順序調(diào)用;3)若虛基類由非虛基類派生而來要先調(diào)用更高級(jí)別基類的構(gòu)造函數(shù)再遵循上述1和2的順序。
3.4虛基類2023-11-16120虛基類初始化順序的簡單舉例:classA;classB;classC:publicA,virtualB
{};將產(chǎn)生如下的調(diào)用次序B()
A()
C()3.4虛基類2023-11-16121較複雜的虛基類初始化舉例:
3.4虛基類2023-11-16122為了避免在不同繼承路徑中繼承來的同一成員發(fā)生多個(gè)副本的衝突可以將相應(yīng)的基類設(shè)為虛基類,見源代碼:sclass3_7.hsmain3_7.cpp運(yùn)行結(jié)果:classBase1classBase2classLevel2classBase2classLevel1classLeaf3.4虛基類2023-11-161233.5聚合類3.5.1聚合類的概念設(shè)計(jì)孤立的類是較容易的,難的是正確設(shè)計(jì)基類及其派生類;一般地如果在邏輯上A是B的一部分而A與B又不屬於同一類範(fàn)疇,則不允許B繼承A的功能而是要用A和其他東西組合出B;聚合(aggregation)也是實(shí)現(xiàn)程式代碼重用的另一有效手段;類的聚合,就是指在一個(gè)類中內(nèi)嵌其他類的對(duì)象作為成員的現(xiàn)象;“擁有”(hasa)關(guān)係,聚合類擁有內(nèi)嵌對(duì)象;出於資訊隱藏的考慮,常將其訪問許可權(quán)設(shè)為“私有”。2023-11-161243.5.2聚合類中的構(gòu)造函數(shù)聚合類對(duì)象在創(chuàng)建時(shí)作為其組成部件的內(nèi)嵌對(duì)象將首先被系統(tǒng)創(chuàng)建;如果一個(gè)聚合類,同時(shí)又是一個(gè)派生類,那麼它的構(gòu)造函數(shù)初始化列表還應(yīng)負(fù)責(zé)為基類構(gòu)造函數(shù)的調(diào)用提供參數(shù);當(dāng)一個(gè)類既是聚合類又是派生類時(shí)的構(gòu)造函數(shù)定義形式:
<類名>::<類名><形參表><基類><形參表><內(nèi)嵌對(duì)象><形參表> { 類的初始化 }3.5聚合類2023-11-16125例3.8公司的每一個(gè)員工都擁有不同的教育背景,其中記錄著畢業(yè)學(xué)校、最高學(xué)歷等基本數(shù)據(jù)??梢詫⒔逃尘俺橄鬄橐粋€(gè)類CEducation,擁有上述數(shù)據(jù),並提供查詢數(shù)據(jù)和顯示數(shù)據(jù)等基本功能。企業(yè)員工類CCompanyStaff要使用教育背景類CEducation的功能,但是前者不能繼承後者所具有的特徵,因此可以把CCompanyStaff類處理成一個(gè)聚合類,在類中內(nèi)嵌一個(gè)Ceducation類的對(duì)象。員工管理系統(tǒng)中的聚合關(guān)係:sclass3_8_companyStaff.hsclass3_8_companyStaff.cppsmain3_8.cpp
3.5聚合類2023-11-161263.6繼承應(yīng)用實(shí)例2.6.1問題描述:該公司的員工組成很簡單,主要分成經(jīng)理,銷售部門經(jīng)理,銷售人員和行政人員等幾類;所有員工都具有姓名,工作編號(hào),基本工資,獎(jiǎng)金,當(dāng)月出勤記錄等數(shù)據(jù),都擁有一定的教育背景;每個(gè)員工都存在錄入和顯示資訊等操作,並且需要根據(jù)考勤等實(shí)際因素來發(fā)放工資;不同類別的員工計(jì)算工資的辦法也各不相同;
例3.9公司員工管理系統(tǒng),根源程式:sclass3_9_companyStaff.hsclass3_9_companyStaff.cppsmain3_9.cpp2023-11-16127習(xí)題課後習(xí)題、作業(yè)習(xí)題1習(xí)題2習(xí)題32023-11-16128Thanks!
TheEnd2023-11-16129函數(shù)重載第四章多態(tài)性132虛函數(shù)多態(tài)性4運(yùn)算符重載內(nèi)容提要2023-11-161304.1多態(tài)性基本概念及其實(shí)現(xiàn)方式多態(tài)性就是一個(gè)事物多種形態(tài),就是同一符號(hào)或者名字在不同情況下具有不同解釋的現(xiàn)象。多態(tài)性有兩種表現(xiàn)形式:一種是不同的對(duì)象在收到相同的消息時(shí),產(chǎn)生不同的動(dòng)作;另一種是同一對(duì)象收到相同的消息卻產(chǎn)生不同的函數(shù)調(diào)用。2023-11-161314.1.2多態(tài)的兩種實(shí)現(xiàn)方式兩種表現(xiàn)形式分別叫做:編譯時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)。(重載)編譯時(shí)多態(tài)——也叫靜態(tài)多態(tài)性,屬於早期綁定,在編譯時(shí)就實(shí)現(xiàn)了綁定,它是靜態(tài)聯(lián)編的;運(yùn)行時(shí)多態(tài)——也叫動(dòng)態(tài)多態(tài)性,屬於晚期綁定,在編譯時(shí)還無法確定綁定對(duì)象,只有在運(yùn)行時(shí)才能夠?qū)崿F(xiàn)綁定,它是動(dòng)態(tài)聯(lián)編的。通過虛函數(shù)實(shí)現(xiàn),動(dòng)態(tài)4.1多態(tài)性基本概念及其實(shí)現(xiàn)方式2023-11-16132以下兩種情況不是動(dòng)態(tài)聯(lián)編的:1、在基類中未使用虛函數(shù)、純虛函數(shù)。2、在基類中使用了虛函數(shù)和純虛函數(shù),但使用對(duì)象直接調(diào)用。這也不是動(dòng)態(tài)聯(lián)編的。使用虛函數(shù)、純虛函數(shù),使用基類的指針或者引用。
4.1多態(tài)性基本概念及其實(shí)現(xiàn)方式2023-11-16133“綁定”——就是讓函數(shù)調(diào)用與函數(shù)體產(chǎn)生關(guān)聯(lián)。在編譯時(shí)就確定——叫“早期綁定”;在程式運(yùn)行時(shí)才確定——叫“晚期綁定”。而C++的多態(tài)性在“早期綁定”和“晚期綁定”兩方面都有體現(xiàn)。4.1多態(tài)性基本概念及其實(shí)現(xiàn)方式2023-11-161344.2虛函數(shù)虛函數(shù)是在基類中使用了關(guān)鍵字virtual的成員函數(shù)。慮函數(shù)與一般函數(shù)重載的區(qū)別:1、虛函數(shù)定義在基類和派生類中,函數(shù)原型完全一致;2、函數(shù)重載在同一個(gè)類中,或者都在類外定義,函數(shù)原型必定不完全相同。虛函數(shù)——運(yùn)行時(shí)多態(tài)2023-11-161354.2.1虛函數(shù)的基本概念及其定義主要通過例子程式說明其機(jī)制.4.2虛函數(shù)2023-11-16136例4_1:利用對(duì)象分別調(diào)用不同的Show()——正確調(diào)用了特定的Show()函數(shù)。s4_1\sclass4_1_student.hs4_1\sclass4_1_student.cpps4_1\smain4_1.cppCPersonoCPerson("德華劉","男"); CStudentoCStudent(20050101,"學(xué)友張","男");oCPerson.Show(); oCStudent.Show(); 4.2虛函數(shù)2023-11-16137在main()中通過“對(duì)象.成員函數(shù)”的形式調(diào)用show(),分別調(diào)用了對(duì)象自己的show()。劉德華|男張學(xué)友|男|200501014.2虛函數(shù)2023-11-16138下麵通過基類指針來調(diào)用,會(huì)有什麼結(jié)果啦?例4_2:利用基類的指針調(diào)用不同的Show()。s4_2\smain4_2.cppch4_2\sclass4_2_student.hch4_2\sclass4_2_student.cpp劉德華|男張學(xué)友|男4.2虛函數(shù)無論讓基類的指針指向基類對(duì)象還是派生類對(duì)象,系統(tǒng)都無法調(diào)用派生類對(duì)象oCStudent的Show()函數(shù)。實(shí)際調(diào)用的都是基類的Show()成員函數(shù)。
2023-11-16139通過基類的引用,引用派生類對(duì)象,會(huì)有什麼結(jié)果啦?例4_3:利用基類的引用作為參數(shù),調(diào)用不同的Show(),依然未達(dá)到目的。
s4_3\smain4_3.cppch4_3\sclass4_3_student.hch4_3\sclass4_3_student.cpp劉德華|男張學(xué)友|男4.2虛函數(shù)2023-11-16140無論引用基類對(duì)象還是派生類對(duì)象,函數(shù)內(nèi)調(diào)用的都是基類的Show()成員函數(shù)。通過基類的引用去引用派生類對(duì)象,只能看到派生類從基類中繼承而來的部分。這是由於C++的靜態(tài)聯(lián)編機(jī)制造成的。它首先將指向基類的指針與基類成員函數(shù)Show()連接在一起。這樣,不管pCPerson指向哪個(gè)對(duì)象,pCPerson->Show()調(diào)用的總是基類的成員函數(shù)Show()。4.2虛函數(shù)2023-11-16141C++提供了虛函數(shù)(virtualfunction)機(jī)制解決上述問題。通過虛函數(shù)機(jī)制,實(shí)現(xiàn)了動(dòng)態(tài)聯(lián)編。一旦基類的成員函數(shù)定義為虛函數(shù),則其派生類的同名成員函數(shù)(原型一致)不管前面是否加關(guān)鍵字virtual,同樣具有虛特性,同樣是虛函數(shù)。虛函數(shù)的傳遞性4.2虛函數(shù)2023-11-16142動(dòng)態(tài)聯(lián)編在多繼承中尤其有用。但虛函數(shù)機(jī)制也是有缺陷的,為了實(shí)現(xiàn)虛特性需要增加一些數(shù)據(jù)存儲(chǔ)和執(zhí)行指令的開銷,虛函數(shù)的使用也不是越多越好。將一個(gè)類中的所有成員函數(shù)都定義為虛函數(shù)(virtual)也是可行的,它除了會(huì)增加一些額外的開銷外,沒有其他更多的壞處,虛函數(shù)對(duì)於保證類的封裝特性是有好處的。4.2虛函數(shù)2023-11-16143虛函數(shù)的“動(dòng)態(tài)聯(lián)編虛特性”必須通過基類的指針或者基類的引用來表現(xiàn)。例4_4:定義了兩個(gè)CPerson的繼承類,具有虛函數(shù)的兩個(gè)實(shí)現(xiàn)版本。s4_4\sclass4_4_student.hs4_4\sclass4_4_student.cpps4_4\smain4_4.cpp虛函數(shù)要求原型一致4.2虛函數(shù)2023-11-161441:-通過基類的引用調(diào)用具有虛特性----德華劉|男學(xué)友張|男|20050101孔老師|男|50002:-通過基類指針調(diào)用具有虛特性----德華劉|男學(xué)友張|男|20050101孔老師|男|50003:-通過對(duì)象調(diào)用則不具有虛特性----德華劉|男學(xué)友張|男|20050101孔老師|男|50004.2虛函數(shù)2023-11-16145在例4_4中,其他代碼不變,將CPerson類聲明部分的“virtualvoidShow()const;”函數(shù)定義語句去掉關(guān)鍵字virtual;改為“voidShow()const;”請(qǐng)問程式的運(yùn)行結(jié)果會(huì)如何?4.2虛函數(shù)2023-11-161461:-通過基類引用調(diào)用(不)具有虛特性---德華劉|男學(xué)友張|男孔老師|男2:-通過基類指針調(diào)用(不)具有虛特性---德華劉|男學(xué)友張|男孔老師|男3:-通過對(duì)象調(diào)用則不具有虛特性---德華劉|男學(xué)友張|男|20050101孔老師|男|50004.2虛函數(shù)2023-11-16147虛函數(shù)的定義要遵循以下幾條重要規(guī)則:1、原型不一致,即使加上了關(guān)鍵字virtual,也不會(huì)進(jìn)行滯後聯(lián)編。2、類的成員函數(shù)才能說明為虛函數(shù)。3、靜態(tài)成員函數(shù)不能是虛函數(shù),靜態(tài)成員函數(shù)是不受某個(gè)對(duì)象的限制,它屬於類。虛函數(shù)必須是成員函數(shù)4.2虛函數(shù)2023-11-161484、內(nèi)聯(lián)(inline)函數(shù)不是虛函數(shù),內(nèi)聯(lián)函數(shù)不能在運(yùn)行時(shí)動(dòng)態(tài)確定位置,它在編譯時(shí)採用插入函數(shù)體的方式處理。。5、構(gòu)造函數(shù)不虛函數(shù),構(gòu)造對(duì)象的時(shí)候,對(duì)象還是一片未定型的空間,只有對(duì)象構(gòu)造完成後,對(duì)象才是具體類的實(shí)例。6、析構(gòu)函數(shù)可以是虛函數(shù),而且通常將析構(gòu)函數(shù)聲明為虛函數(shù)。有兒子,則其析構(gòu)函數(shù)需要是虛函數(shù)4.2虛函數(shù)2023-11-161494.2.2虛函數(shù)與重載函數(shù)的關(guān)係1、重載函數(shù)函數(shù)名稱相同,參數(shù)不同;重載函數(shù)是在作用域相同的區(qū)域裏定義的相同名字的不同函數(shù).2、虛函數(shù)函數(shù)原型完全一致,體現(xiàn)在基類和派生類的類層次結(jié)構(gòu)中。3、重載函數(shù)可以是成員函數(shù)或友員函數(shù),而虛函數(shù)只能是成員函數(shù);4、調(diào)用重載函數(shù)以所傳遞參數(shù)序列的差別作為調(diào)用不同函數(shù)的依據(jù);虛函數(shù)則根據(jù)對(duì)象的不同調(diào)用不同類的虛函數(shù);5、重載函數(shù)在編譯時(shí)表現(xiàn)出多態(tài)性,是靜態(tài)聯(lián)編;而虛函數(shù)在運(yùn)行時(shí)表現(xiàn)出多態(tài)性,是動(dòng)態(tài)聯(lián)編,動(dòng)態(tài)聯(lián)編是C++的精髓。4.2虛函數(shù)2023-11-161504.2.3虛函數(shù)與函數(shù)隱藏和函數(shù)覆蓋基類和派生類中的原型一致的函數(shù),如果是虛函數(shù),則稱為覆蓋;如果原型一致的函數(shù)不是虛函數(shù),就稱為隱藏。原型不一致的話,不管是否虛函數(shù),都稱為隱藏。虛函數(shù)才有可能覆蓋4.2虛函數(shù)2023-11-16151覆蓋和隱藏適用下述規(guī)則(基類和派生類):
1、完全同名,參數(shù)不同,不論是否虛函數(shù),基類的函數(shù)將被隱藏。2、如果派生類的函數(shù)與基類的函數(shù)同名,並且參數(shù)也相同,但是基類函數(shù)不是虛函數(shù)。此時(shí),基類的函數(shù)被隱藏。3、如果派生類的函數(shù)與基類的函數(shù)同名,並且參數(shù)也相同,基類函數(shù)也是虛函數(shù)。此時(shí),基類的函數(shù)被覆蓋了。4.2虛函數(shù)2023-11-16152另外,當(dāng)基類中的虛函數(shù)和派生類中的函數(shù)原型出現(xiàn)不同時(shí),將按照以下兩種情況處理:1、僅僅返回值類型不同,其餘均相同,系統(tǒng)會(huì)當(dāng)作錯(cuò)誤處理。僅僅返回值不同的函數(shù)本質(zhì)上是含糊的。2、函數(shù)原型不同,僅函數(shù)名相同。此時(shí)系統(tǒng)將認(rèn)為它是重定義函數(shù),將丟失虛特性,且該函數(shù)還會(huì)隱藏基類同名函數(shù)。4.2虛函數(shù)2023-11-16153例4_5:重載、隱藏和覆蓋。
s4_5\sclass4_5_student.hs4_5\sclass4_5_student.cpps4_5\smain4_5.cpp函數(shù)名相同,原型不同的虛函數(shù)或非虛函數(shù),在派生類中都被隱藏;原型相同的虛函數(shù)在派生類中被覆蓋;原型相同的非虛函數(shù)在派生類中被隱藏。4.2虛函數(shù)2023-11-161544.2.4多重繼承中的虛函數(shù)虛函數(shù)具有傳遞性,具有虛函數(shù)的基類指針可以指向它的派生類,也可以指向它的派生類的派生類,它們都具有動(dòng)態(tài)特性。為了實(shí)現(xiàn)多重繼承中虛函數(shù)的傳遞性,在派生時(shí),需要採用public繼承方式,否則無法實(shí)現(xiàn)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年的借款合同模板
- 2025深圳市汽車租賃合同范本
- 2025婚慶舞臺(tái)音響燈光租賃合同范本
- 2025江蘇南京市房屋租賃合同
- 2025年銀行從業(yè)人員考試題庫及答案
- 2025【總承包合同】勞務(wù)分包協(xié)議
- 2025個(gè)人汽車(車輛按揭)借款合同 中國建設(shè)銀行福建省分行
- 2025年炭黑原材料采購合同樣本
- 2025標(biāo)準(zhǔn)版房屋租賃合同范本2
- 2025國內(nèi)產(chǎn)品交易合同
- 安全生產(chǎn)投入臺(tái)賬(模板)
- 清華大學(xué)領(lǐng)軍計(jì)劃語文試題強(qiáng)基計(jì)劃
- 醫(yī)療欠款欠條范本
- 母親節(jié)健康科普知識(shí)
- 《奧爾夫音樂教學(xué)法》課程標(biāo)準(zhǔn)
- 茶葉產(chǎn)品報(bào)價(jià)函
- 膀胱結(jié)石護(hù)理課件
- 生產(chǎn)工藝驗(yàn)證方案(藥品)
- 企業(yè)增長組合戰(zhàn)略理論
- 建筑工程幕墻工程作業(yè)活動(dòng)風(fēng)險(xiǎn)分級(jí)管控清單
- 建設(shè)工程消防竣工驗(yàn)收統(tǒng)計(jì)表(樣表)
評(píng)論
0/150
提交評(píng)論