版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
類的繼承與多態(tài)性第一頁(yè),共六十頁(yè),2022年,8月28日本章內(nèi)容類的繼承類的虛函數(shù)與多態(tài)性類的靜態(tài)成員類模板第二頁(yè),共六十頁(yè),2022年,8月28日一、繼承的概念繼承是軟件重用的一種方式。通過(guò)繼承建立新類的優(yōu)越性:通過(guò)重用已有代碼,提高編程效率,降低軟件開發(fā)成本;更有效地保持共有特性的一致性;提高了系統(tǒng)的可維護(hù)性;是實(shí)現(xiàn)多態(tài)性的基礎(chǔ)。被繼承的類稱為“父類”或“基類”
;繼承者被稱為“子類”或“派生類”;§9.1類的繼承第三頁(yè),共六十頁(yè),2022年,8月28日繼承體現(xiàn)了類的“層次”,從層次上來(lái)說(shuō),就是位于上層的是基類,下層的為派生類;派生類吸收了基類的非private成員,并增添新的性能?;悺⑴缮愂窍鄬?duì)的。第四頁(yè),共六十頁(yè),2022年,8月28日基類與派生類示例基類派生類學(xué)生本科生,研究生形狀圓,三角形,矩形,球體,立方體貸款汽車貸款,住房貸款,抵押貸款雇員教職員工,后勤人員賬戶支票賬戶,儲(chǔ)蓄賬戶一般地,派生類的對(duì)象都“是”其基類的一個(gè)對(duì)象;基類所能表示的對(duì)象集合比派生類所表示的對(duì)象集合大.eg.矩形類“是”四邊形類,反之不成立.第五頁(yè),共六十頁(yè),2022年,8月28日單繼承建筑物房屋橋梁紀(jì)念塔平房樓房居民樓辦公樓單繼承:派生類僅由一個(gè)基類派生而來(lái)第六頁(yè),共六十頁(yè),2022年,8月28日多繼承EmployeeFacultyStaffAdministratorTeacherAdministratorteacher多重繼承:派生類由多于一個(gè)的基類派生而成多級(jí)繼承:等于或多于兩個(gè)的繼承層次第七頁(yè),共六十頁(yè),2022年,8月28日二、派生類的定義定義格式:
class<派生類名>:<繼承方式><基類名>
{派生類新定義成員};繼承方式包括:
public/protected/private
分別表示派生類公有繼承基類,
派生類保護(hù)繼承基類,
派生類私有繼承基類.classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB:publicA{public:B(intbb=0){b=bb;}private:intb;};第八頁(yè),共六十頁(yè),2022年,8月28日聚合VS繼承聚合:B類對(duì)象的成員包括A類的一個(gè)或多個(gè)對(duì)象。繼承:B類對(duì)象的成員包括A類的成員。classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB:publicA{public:B(intbb=0){b=bb;}private:intb;};classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB{public:B(intbb=0):aa(0){b=bb;}private:intb;
Aaa;};B-b:int+showA(),+B()B-b:int,-aa:A+B()第九頁(yè),共六十頁(yè),2022年,8月28日派生類成員的構(gòu)成后舉例基類中的私有成員不能被派生類成員直接引用。派生類對(duì)象先存儲(chǔ)其基類子對(duì)象部分,再存儲(chǔ)新增部分。第十頁(yè),共六十頁(yè),2022年,8月28日派生類成員和外部對(duì)象訪問(wèn)基類中的私有成員派生類專屬成員使用基類私有成員的方式:①不能直接使用基類中的私有成員;②成員函數(shù)方式:派生類成員函數(shù)需要通過(guò)基類提供的公有或保護(hù)成員函數(shù)間接訪問(wèn);外部對(duì)象通過(guò)基類的公有成員函數(shù)使用其私有成員;③友元方式:把派生類定義為基類的友元,則派生類成員可以直接使用基類成員;而派生類對(duì)象則可以用友元函數(shù)間接使用基類私有成員.第十一頁(yè),共六十頁(yè),2022年,8月28日派生類的三種繼承方式公有繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員分別成為派生類的公有成員和保護(hù)成員。私有繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員將成為派生類的私有成員。保護(hù)繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員將成為派生類的保護(hù)成員。第十二頁(yè),共六十頁(yè),2022年,8月28日繼承方式基類成員public方式派生類內(nèi)/類外對(duì)象private方式派生類內(nèi)/類外對(duì)象protected方式派生類內(nèi)/類外對(duì)象private不可見不可見不可見protected可見/不可見可見/不可見可見/不可見public可見可見/不可見可見/不可見三種繼承方式存取權(quán)限的關(guān)系類內(nèi):指派生類內(nèi)的成員函數(shù)類外:指類外部定義的派生類對(duì)象可見:即可以直接訪問(wèn)(使用)不可見:只能間接訪問(wèn)第十三頁(yè),共六十頁(yè),2022年,8月28日繼承成員的訪問(wèn)屬性---舉例示例
classX{private:inta;protected:intb;public:intc;};classY1:publicX{intd;public:
output(){returnd;}};Y1的構(gòu)成-----
私有:d
保護(hù):b
公有:output(),c不可直接訪問(wèn):a(仍屬于基類)第十四頁(yè),共六十頁(yè),2022年,8月28日繼承成員的訪問(wèn)屬性---舉例示例classX{private:inta;protected:intb;public:intc;};classY2:protectedX{intd;public:
output(){returnd;}};Y2的構(gòu)成----
私有:d
保護(hù):bc
公有:output()
不可直接訪問(wèn):a(仍屬于基類)第十五頁(yè),共六十頁(yè),2022年,8月28日繼承成員的訪問(wèn)屬性---舉例示例classX{private:inta;protected:intb;public:intc;};classY3:private
X{intd;public:
output(){returnd;}};Y3的構(gòu)成----
私有:dbc
保護(hù):公有:output()
不可直接訪問(wèn):a(仍屬于基類)第十六頁(yè),共六十頁(yè),2022年,8月28日(1)public繼承方式在public繼承方式下,派生類內(nèi)的成員函數(shù)中可以訪問(wèn)基類和派生類中的保護(hù)成員,但外部程序中定義的派生類對(duì)象不可訪問(wèn)基類和派生類中的保護(hù)成員。Eg.例題“public繼承”在public繼承方式下,派生類內(nèi)的成員函數(shù)中可以訪問(wèn)基類和派生類中的保護(hù)成員,但外部程序中定義的派生類對(duì)象不可訪問(wèn)基類和派生類中的保護(hù)成員。Eg.例題“private繼承”(2)private繼承方式第十七頁(yè),共六十頁(yè),2022年,8月28日Eg.例題“public繼承”#include<isotream.h>classA{private:inta1;protected:inta2;public:inta3;A(intx1,intx2,intx3):A(x1),a2(x2),a3(x3){}~A(){}};classB:publicA{private:intb1;protected:intb2;public:intb3;B(intx1,intx2,intx3,inty1,inty2,inty3):A(x1,x2,x3),b1(y1),b2(y2),b3(y3){}~B(){}voidprint()const;};voidB::print()const{//cout<<“a1=”<<a1<<endl;//非法
cout<<“a2=”<<a2<<endl;cout<<“a3=”<<a3<<endl;cout<<“b1=”<<b1<<endl;cout<<“b2=”<<b2<<endl;cout<<“b3=”<<b3<<endl;}voidshow(B&myB){//cout<<myB.a1<<myB.a2<<endl;//非法
cout<<“a3=”<<myB.a3<<endl;//cout<<myB.b1<<myB.b2<<endl;//非法
cout<<“b3=”<<myB.b3<<endl;第十八頁(yè),共六十頁(yè),2022年,8月28日Eg.例題“private繼承”#include<isotream.h>classA{private:inta1;protected:inta2;public:inta3;A(intx1,intx2,intx3):A(x1),a2(x2),a3(x3){}~A(){}};classB:privateA{private:intb1;protected:intb2;public:intb3;B(intx1,intx2,intx3,inty1,inty2,inty3):A(x1,x2,x3),b1(y1),b2(y2),b3(y3){}~B(){}voidprint();};voidB::print(){//cout<<“a1=”<<a1<<endl;//非法
cout<<“a2=”<<a2<<“a3=”<<a3<<endl;cout<<“b1=”<<b1<<“b2=”<<b2<<endl;cout<<“b3=”<<b3<<endl;}voidshow(AmyA,B&myB){//cout<<myA.a1<<myA.a2;非法
cout<<myA.a3<<endl;//cout<<“myB.a1<<myB.a2<<endl;//非法
//cout<<“a3=”<<myB.a3<<endl;//非法
//cout<<myB.b1<<myB.b2<<endl;//非法
cout<<“b3=”<<myB.b3<<endl;第十九頁(yè),共六十頁(yè),2022年,8月28日三、派生類的構(gòu)造函數(shù)繼承關(guān)系中,基類的兩個(gè)特殊成員函數(shù)---構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被繼承。因此,派生類的構(gòu)造函數(shù)不僅要初始化派生類中定義的數(shù)據(jù)成員,而且要初始化派生類中的基類子對(duì)象(派生類對(duì)象中由基類定義的部分稱作基類子對(duì)象)?;愖訉?duì)象的初始化賦值是通過(guò)在派生類構(gòu)造函數(shù)中顯式或隱式地調(diào)用基類構(gòu)造函數(shù)實(shí)現(xiàn)的。構(gòu)造函數(shù)的執(zhí)行順序:先執(zhí)行基類構(gòu)造函數(shù),再執(zhí)行派生類構(gòu)造函數(shù)?;愖訉?duì)象派生類專有部分派生類第二十頁(yè),共六十頁(yè),2022年,8月28日例1:P267例題classA
{
inta1;
protected:
inta2;
public:
inta3;
A(){a1=a2=a3=0;}
A(intx1,intx2,intx3):a1(x1),a2(x2),a3(x3){}
voidout(){cout<<a1<<‘‘<<a2<<‘‘<<a3<<endl;}
intGeta1(){returna1;}
};返回B類第二十一頁(yè),共六十頁(yè),2022年,8月28日classB:publicA{
intb1;
protected:
intb2;
public:
intb3;
B(){b1=b2=b3=0;}
B(intx1,intx2,intx3):A(x1,x2,x3)
{b1=x1+1;b2=x2+2;b3=x3+3;}
voidout(){A::out();
cout<<b1<<‘‘<<b2<<‘‘<<b3<<endl;}
intSum(){returnGeta1()*b1+a2*b2+a3*b3;}};隱含調(diào)用A()顯式調(diào)用
A(int,int,int)調(diào)用類A中的無(wú)參構(gòu)造函數(shù)返回main()函數(shù)//A類和B類中都有Out(),則用::界定其所屬,若不加則指的是本類成員.調(diào)用類A中的帶參構(gòu)造函數(shù)第二十二頁(yè),共六十頁(yè),2022年,8月28日
voidmain(){
Bb1,b2(1,2,3);b1.Out();b2.Out();cout<<b1.Sum()<<‘
‘<<b2.Sum()<<endl;cout<<sizeof(B)<<endl;}調(diào)用類B中的構(gòu)造函數(shù)初始化對(duì)象第二十三頁(yè),共六十頁(yè),2022年,8月28日四、派生類的析構(gòu)函數(shù)撤銷派生類對(duì)象時(shí),系統(tǒng)先自動(dòng)調(diào)用派生類的析構(gòu)函數(shù),再調(diào)用基類的析構(gòu)函數(shù)。系統(tǒng)對(duì)派生類和基類析構(gòu)函數(shù)的自動(dòng)調(diào)用順序和其對(duì)構(gòu)造函數(shù)的調(diào)用順序正好相反。例:類層次中普通析構(gòu)函數(shù)第二十四頁(yè),共六十頁(yè),2022年,8月28日五、基類和派生類的賦值兼容規(guī)則在滿足公有繼承的限制條件下,C++允許派生類對(duì)象到基類對(duì)象的自動(dòng)轉(zhuǎn)換,通常稱為賦值兼容規(guī)則。規(guī)則1:可以用派生類對(duì)象為基類對(duì)象賦值規(guī)則2:可以用派生類對(duì)象初始化基類的引用對(duì)象規(guī)則3:可以用基類的指針指向派生類對(duì)象eg.賦值兼容規(guī)則eg.類層次中普通析構(gòu)函數(shù)第二十五頁(yè),共六十頁(yè),2022年,8月28日§9.2多重繼承多級(jí)繼承引例:Windows風(fēng)格用戶界面設(shè)計(jì)先設(shè)計(jì)出窗口類、尺寸類、橫向/縱向滾動(dòng)條類、按鈕類;用戶界面類將上述各類作為基類,通過(guò)多重繼承產(chǎn)生。一、多重繼承時(shí)的派生類
1、定義格式:
class派生類名:
[繼承方式1][基類名1],[繼承方式2][基類名2],…{派生類成員定義};注:各基類名不能相同第二十六頁(yè),共六十頁(yè),2022年,8月28日2、初始化數(shù)據(jù)成員—調(diào)用構(gòu)造函數(shù)1)調(diào)用順序構(gòu)造函數(shù)調(diào)用順序:
(1)初始化第一個(gè)基類子對(duì)象,即調(diào)用第一個(gè)基類的構(gòu)造函數(shù);初始化第二個(gè)基類子對(duì)象,即調(diào)用第二個(gè)基類的構(gòu)造函數(shù);
…
…
初始化第n個(gè)基類子對(duì)象,即調(diào)用第n個(gè)基類的構(gòu)造函數(shù)。
(2)派生類中若有基類對(duì)象作成員,則調(diào)用相應(yīng)基類的構(gòu)造函數(shù)。
(3)最后初始化派生類普通成員。析構(gòu)函數(shù)調(diào)用順序:與構(gòu)造函數(shù)相反。第二十七頁(yè),共六十頁(yè),2022年,8月28日例:多重繼承時(shí)的構(gòu)造函數(shù)的調(diào)用P269說(shuō)明:派生類初始化成員的順序:
首先對(duì)基類子對(duì)象成員的初始化,
然后對(duì)新增對(duì)象成員初始化,
最后對(duì)新增非對(duì)象成員初始化.注:前兩步必須在構(gòu)造函數(shù)的初值表中給出初值項(xiàng)
(省略時(shí)調(diào)用無(wú)參構(gòu)造函數(shù));
后一步可以通過(guò)初值表,也可以通過(guò)函數(shù)體進(jìn)行.第二十八頁(yè),共六十頁(yè),2022年,8月28日二、多級(jí)繼承中的派生類
classA{};classB:publicA{};classC:publicB{};B直接繼承類A,C直接繼承類B,間接繼承類A。eg.P270多級(jí)繼承舉例多級(jí)繼承時(shí)的初始化順序:先執(zhí)行最上層基類的構(gòu)造函數(shù),依次向下執(zhí)行各基類的構(gòu)造函數(shù),最后是當(dāng)前派生類的構(gòu)造函數(shù)對(duì)新增成員的初始化.第二十九頁(yè),共六十頁(yè),2022年,8月28日?qǐng)?zhí)行C的構(gòu)造函數(shù)前先調(diào)用B1、B2構(gòu)造函數(shù);執(zhí)行B1、B2構(gòu)造函數(shù)前先分別調(diào)用A的構(gòu)造函數(shù)。AB1B2CA為C的公共基類eg.數(shù)據(jù)成員二義性三、混合多繼承中的構(gòu)造函數(shù)classC:publicB1,publicB2{};第三十頁(yè),共六十頁(yè),2022年,8月28日1、數(shù)據(jù)成員二義性假設(shè)圖中類A有數(shù)據(jù)成員a,則C中有兩個(gè)a成員,a是哪個(gè)派生類的成員?產(chǎn)生了二義性。解決方法:
(1)加類名分辨符B1::或B2::(2)定義虛基類
eg1.數(shù)據(jù)成員二義性A(a)B1(a,b1)B2(a,b2)C(a,b1,b2,c)四、多繼承中二義性問(wèn)題的解決第三十一頁(yè),共六十頁(yè),2022年,8月28日2、函數(shù)成員二義性
B1,B2中都含有print()成員函數(shù),C繼承了B1,B2,則C中有兩個(gè)print()函數(shù)。解決方法:加類區(qū)分符::eg2.函數(shù)成員二義性B1(print())B2(print())C第三十二頁(yè),共六十頁(yè),2022年,8月28日§9.3虛基類消除數(shù)據(jù)成員二義性的兩種方法的區(qū)別:
(1)”類名::”法:消除二義性同時(shí)實(shí)現(xiàn)程序設(shè)計(jì)的多態(tài)性,但在派生類對(duì)象中存在多個(gè)公共基類的同名數(shù)據(jù)成員
(2)”虛函數(shù)”法:消除二義性,且在派生類對(duì)象中只存在一個(gè)公共基類的數(shù)據(jù)成員設(shè)計(jì)虛基類:
(1)一個(gè)基類有多于一個(gè)派生類時(shí),在這些派生類“繼承方式”前加上
virtual關(guān)鍵字。
classB1:virtualpublicAclassB2:virtualpublicA
此時(shí)將公共基類A稱為虛基類。AB1B2C第三十三頁(yè),共六十頁(yè),2022年,8月28日(2)虛基類子對(duì)象由最新派生出來(lái)的派生類直接初始化。
B1,B2對(duì)類A子對(duì)象初始化,
C也要對(duì)類A子對(duì)象初始化。
eg.虛基類注意:對(duì)非虛基類,不能在C中對(duì)A類子對(duì)象初始化。AB1B2C第三十四頁(yè),共六十頁(yè),2022年,8月28日§9.4類的虛函數(shù)和多態(tài)性對(duì)于相同的函數(shù)調(diào)用,依賴每個(gè)對(duì)象自己做出恰當(dāng)?shù)捻憫?yīng),這是多態(tài)性的關(guān)鍵思想。多態(tài)性(polymorphism):不同對(duì)象在接收同樣的消息時(shí),所做出的響應(yīng)不同。多態(tài)性的實(shí)現(xiàn)依賴于動(dòng)態(tài)聯(lián)編。指調(diào)用名稱相同的成員函數(shù)指不同派生類的成員函數(shù)第三十五頁(yè),共六十頁(yè),2022年,8月28日一、滯后聯(lián)編
聯(lián)編:指一個(gè)標(biāo)識(shí)符名和一個(gè)存儲(chǔ)地址聯(lián)系在一起的過(guò)程。
1、靜態(tài)聯(lián)編(早期聯(lián)編)指:聯(lián)編工作出現(xiàn)在編譯連接階段,因?yàn)檫@種聯(lián)編過(guò)程在程序開始運(yùn)行之前完成,所以又稱早期聯(lián)編。在編譯時(shí)就解決了程序中的操作調(diào)用與執(zhí)行該操作代碼間的關(guān)系,確定這種關(guān)系又被稱為束定,因此,靜態(tài)聯(lián)編又稱為靜態(tài)束定。
2、動(dòng)態(tài)聯(lián)編(滯后聯(lián)編)指:在程序執(zhí)行時(shí)進(jìn)行的聯(lián)編,稱動(dòng)態(tài)聯(lián)編,或稱動(dòng)態(tài)束定,又叫滯后聯(lián)編。動(dòng)態(tài)聯(lián)編時(shí)在不同階段被束定的類的對(duì)象將是不同的。動(dòng)態(tài)聯(lián)編的實(shí)現(xiàn):C++中,在虛函數(shù)的支持下實(shí)現(xiàn)。第三十六頁(yè),共六十頁(yè),2022年,8月28日二、虛函數(shù)的定義1、定義:virtual成員函數(shù)原型;2、注意:
(1)只有在類的繼承關(guān)系中才存在虛函數(shù)。在基類中聲明某成員函數(shù)為虛函數(shù),則派生類中(名字、參數(shù)個(gè)數(shù)、參數(shù)類型和返回值類型都)相同的成員函數(shù)都視作虛函數(shù)。
(2)使用虛函數(shù)須利用賦值兼容規(guī)則,要求public繼承方式。
(3)多態(tài)性使我們編寫的程序在處理同一個(gè)類層次結(jié)構(gòu)下類的對(duì)象時(shí)好像它們是基類的所有對(duì)象一樣。第三十七頁(yè),共六十頁(yè),2022年,8月28日三、虛函數(shù)的使用多態(tài)性是利用基類的指針句柄和基類的引用句柄,而不是利用名字句柄。實(shí)現(xiàn)多態(tài)的步驟:
(1)定義基類指針
(2)用該指針指向基類或派生類對(duì)象
(3)當(dāng)程序發(fā)送虛函數(shù)消息時(shí):若指針指向基類對(duì)象,系統(tǒng)調(diào)用基類成員函數(shù),若指針指向派生類對(duì)象,系統(tǒng)調(diào)用派生類成員函數(shù)。
(4)若沒(méi)有步驟(2)中賦值,系統(tǒng)按早期聯(lián)編方式調(diào)用基類成員函數(shù)。第三十八頁(yè),共六十頁(yè),2022年,8月28日classX1{intx;public:X1(intxx=0){x=xx;}virtualvoidOutput(){cout<<“x=“<<x<<endl;}};classY1:publicX1{inty;public:Y1(intxx=0,intyy=0):X1(xx){y=yy;}virtualvoidOutput(){X1::Output();cout<<“y=“<<y<<endl;}};可以去掉這里的virtual例:虛函數(shù)第三十九頁(yè),共六十頁(yè),2022年,8月28日classZ1:publicX1{intz;public:Z1(intxx=0,intzz=0):X1(xx){z=zz;}virtualvoidOutput(){X1::Output();cout<<“z=“<<z<<endl;}};voidmain(){X1a(5);Y1b(6,7);Z1c(8,9);X1*p[3]={&a,&b,&c};for(inti=0;i<3;i++){p[i]->Output();cout<<endl;}}結(jié)論:定義了虛函數(shù)后,通過(guò)基類指針調(diào)用虛函數(shù)時(shí),實(shí)際被調(diào)用的是指針?biāo)笇?duì)象內(nèi)的函數(shù);結(jié)果:x=5
x=6
Y=7
x=8
z=9不定義虛函數(shù)時(shí)的結(jié)果:x=5
x=6
x=8基類子對(duì)象派生類專有部分派生類第四十頁(yè),共六十頁(yè),2022年,8月28日虛函數(shù)的調(diào)用說(shuō)明:使用基類指針指向其派生類的對(duì)象;相同的調(diào)用方式實(shí)際上能夠調(diào)用一組中的任何一個(gè)派生類中的虛函數(shù),即是多態(tài)性。由于被實(shí)際調(diào)用的函數(shù)是在運(yùn)行時(shí)確定的,因此稱為動(dòng)態(tài)綁定虛函數(shù)的使用限制:只能通過(guò)指針或引用調(diào)用虛函數(shù);如果用普通對(duì)象名調(diào)用虛函數(shù),將釆用靜態(tài)聯(lián)編方式;虛函數(shù)定義時(shí),函數(shù)名、返回類型、參數(shù)類型、個(gè)數(shù)和順序與基類中的函數(shù)定義應(yīng)完全一致。(不同于重載函數(shù))構(gòu)造函數(shù)不能定義為虛函數(shù),但析構(gòu)函數(shù)可以。第四十一頁(yè),共六十頁(yè),2022年,8月28日voidmain(){Bb;
b.act2();}考慮:
1、程序結(jié)果是什么?
2、如果將A中act2()實(shí)現(xiàn)為:
voidA::act2(){this->act1();}
結(jié)果如何?
3、如果將A中act1()前的virtual
去掉,結(jié)果如何?例:#include<iostream.h>classA{public:
virtualvoidact1();voidact2(){act1();}};voidA::act1(){cout<<“A::act1()called.”<<endl;}classB:publicA{public:
voidact1();};voidB::act1(){cout<<“B::act1()called.”<<endl;}B::act1()called.B::act1()called.A::act1()called.可以由成員函數(shù)調(diào)用虛函數(shù)第四十二頁(yè),共六十頁(yè),2022年,8月28日四、構(gòu)造函數(shù)中調(diào)用虛函數(shù)#include<iostream.h>classA{public:A(){}virtualvoidf(){cout<<“A::f()called.\n”;}};classB:publicA{public:B(){f();}voidg(){f();}};classC:publicB{public:C(){}virtualvoidf(){cout<<“C::f()called.\n”;}};voidmain(){Cc;c.g();}結(jié)果:A::f()called.C::f()called.結(jié)論:構(gòu)造函數(shù)中調(diào)用虛函數(shù)時(shí),釆用靜態(tài)聯(lián)編,即構(gòu)造函數(shù)調(diào)用的虛函數(shù)是自己類中實(shí)現(xiàn)的虛函數(shù),如果自己類中沒(méi)有實(shí)現(xiàn)這個(gè)虛函數(shù),則調(diào)用基類中的虛函數(shù)。第四十三頁(yè),共六十頁(yè),2022年,8月28日例:定義普通析構(gòu)函數(shù)#include<iostream.h>classAA{inti;public:AA(intn):i(n){}~AA(){cout<<“AA“<<endl;}};classBB:publicAA{char*p;public:BB(intn,char*s):AA(n){p=newchar[strlen(s)+1];strcpy(p,s);}~BB(){deletep;cout<<“BB”<<endl;}};voidmain(){AA*p=newBB(5,”abcd”);
deletep;
};結(jié)果:AA普通析構(gòu)函數(shù)在使用delete刪除一個(gè)對(duì)象時(shí),是靜態(tài)聯(lián)編,關(guān)聯(lián)的只是基類的析構(gòu)函數(shù)。五、虛析構(gòu)函數(shù)第四十四頁(yè),共六十頁(yè),2022年,8月28日#include<iostream.h>classAA{inti;public:AA(intn):i(n){}virtual~AA(){cout<<“AA“<<endl;}};classBB:publicAA{char*p;public:BB(intn,char*s):AA(n){p=newchar[strlen(s)+1];strcpy(p,s);}~BB(){deletep;cout<<“BB”<<endl;}};voidmain(){AA*p=newBB(5,”abcd”);
deletep;
};結(jié)果:BB
AA虛析構(gòu)函數(shù)的目的在于使用delete刪除一個(gè)對(duì)象時(shí),是動(dòng)態(tài)聯(lián)編,關(guān)聯(lián)的是子類的析構(gòu)函數(shù)。例:定義虛析構(gòu)函數(shù)第四十五頁(yè),共六十頁(yè),2022年,8月28日六、純虛函數(shù)與抽象類軟件使用者:某軟件只要用到一些具體事物的類(如:Sphere,Cylinder,Cone類)
軟件設(shè)計(jì)者:增加一個(gè)更抽象的基類效果更好(代碼重用)(如:Circle類)--某些成員函數(shù)在基類中的實(shí)現(xiàn)變得沒(méi)意義(如:Area(),Volume()函數(shù)),但其聲明仍有意義。
問(wèn)題:能否將這樣的成員函數(shù)在基類中只作聲明,而其實(shí)現(xiàn)留給派生類呢?
用純虛函數(shù)將基類改造為抽象類第四十六頁(yè),共六十頁(yè),2022年,8月28日1、純虛函數(shù)定義:
virtual返回類型函數(shù)名(參數(shù)表)=0純虛函數(shù)在基類中聲明,具體實(shí)現(xiàn)在派生類中。2、抽象類包含純虛函數(shù)的類稱為抽象類。抽象類為其所有子類提供了統(tǒng)一的操作界面。說(shuō)明:抽象類不能實(shí)例化,即不能聲明抽象類對(duì)象;抽象類只作為基類被繼承,無(wú)派生類的抽象類無(wú)意義可定義指向抽象類的指針或引用,它們必然指向派生類對(duì)象,從而實(shí)現(xiàn)多態(tài)性。第四十七頁(yè),共六十頁(yè),2022年,8月28日例:純虛函數(shù)與抽象類classShape{public:
virtualdoublearea()=0;};classPoint{doublex,y;public:Point(doublex0=0.0,doubley0=0.0):x(x0),y(y0){}doublegetX(){returnx;}doublegetY(){returny;}};第四十八頁(yè),共六十頁(yè),2022年,8月28日classRectAngle:publicShape{Pointul;//左下角頂點(diǎn)
Pointdr;//右上角頂點(diǎn)public:RectAngle(Pointp1,Pointp2):ul(p1),dr(p2){}
virtualdoublearea(){
return(dr.getX()-ul.getX())*(dr.getY()-ul.getY());
}PointgetUpleft(){returnul;}PointgetDownright(){returndr;}};第四十九頁(yè),共六十頁(yè),2022年,8月28日classCircle:publicShape{Pointcen;//圓心
doublerad;//半徑public:Circle(Pointc,doubler):cen(c),rad(r){}
virtualdoublearea(){return3.1415926*rad*rad;}PointgetCenter(){returncen;}doublegetRadius(){returnrad;}};voidshowArea(Shape&s){cout<<s.area();}voidmain(){RectAngle
r(Point(2.0,2.0),Point(8.0,8.0));
showArea(r);cout<<endl;Circlec(Point(8,8),4);
showArea(c);}通過(guò)調(diào)用showArea()這同一動(dòng)作,計(jì)算出不同形狀的面積,即同一消息,不同響應(yīng)-----多態(tài)性。第五十頁(yè),共六十頁(yè),2022年,8月28日類非static數(shù)據(jù)成員函數(shù)成員對(duì)象1非static數(shù)據(jù)成員對(duì)象2非static數(shù)據(jù)成員對(duì)象n非static數(shù)據(jù)成員第五十一頁(yè),共六十頁(yè),2022年,8月28日類數(shù)據(jù)成員函數(shù)成員static數(shù)據(jù)成員對(duì)象1對(duì)象2對(duì)象n對(duì)象3第五十二頁(yè),共六十頁(yè),2022年,8月28日§9.5類的靜態(tài)成員在類成員聲明前加上static修飾即把該成員聲明為該類的靜態(tài)成員;static數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員必須在定義第一個(gè)對(duì)象之前作為靜態(tài)變量加以定義并初始化;靜態(tài)函數(shù)成員沒(méi)有this指針,只能直接訪問(wèn)類中的靜態(tài)成員(如要訪問(wèn)類中非靜態(tài)成員,必須借助對(duì)象名或指向?qū)ο蟮闹羔槪?。靜態(tài)成員不能說(shuō)明為虛函數(shù)。一般地,每個(gè)對(duì)象都存放有其所屬類中所有成員的拷貝.
非static數(shù)據(jù)成員但有時(shí)希望程序中的同類對(duì)象共享某個(gè)成員,解決方法:(一)將要共享成員說(shuō)明為全局變量---破壞封裝性(二)將要共享成員說(shuō)明成類的靜態(tài)成員---較好第五十三頁(yè),共六十頁(yè),2022年,8月28日例1:類的靜態(tài)數(shù)據(jù)成員classXX{inta;public:
staticintb;XX(intaa=0){a=aa;b++;}intgeta(){returna;}};intXX::b=0;voidmain(){cout<<XX::b<<endl;XXx(10),y(20);cout<<x.geta()<<“,”<<x.b<<endl;cout<<y.geta()<<“,“<<y.b<<endl;}x.ay.aXX::b結(jié)果:010,220,2靜態(tài)數(shù)據(jù)成員可以用來(lái)計(jì)數(shù),本題中可以用來(lái)計(jì)該類定義的對(duì)象的個(gè)數(shù)第五十四頁(yè),共六十頁(yè),2022年,8月28日classMOD100{public:staticintadd(intx,inty){return(x+y)%100;}staticintsub(intx,inty){return(x-y)%100;}};voidmain(){cout<<MOD100::add(34,89)<<endl;cout<<MOD100::sub(34,199)<<
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2020-2025年中國(guó)原酒行業(yè)市場(chǎng)調(diào)研分析及投資前景預(yù)測(cè)報(bào)告
- 二零二五年度外籍員工社會(huì)保險(xiǎn)繳納管理合同
- 2025年中國(guó)氬弧焊機(jī)行業(yè)市場(chǎng)深度分析及投資戰(zhàn)略規(guī)劃報(bào)告
- 二零二五年度凈水器新型濾芯研發(fā)與售后服務(wù)合同3篇
- 2025年新型護(hù)欄施工與節(jié)能環(huán)保承包協(xié)議下載
- 2025版充電樁充電站安全防護(hù)與應(yīng)急救援合同3篇
- 2025年中國(guó)亞麻面料行業(yè)發(fā)展前景預(yù)測(cè)及投資戰(zhàn)略研究報(bào)告
- 2025年度車輛抵押借款合同信用評(píng)估協(xié)議4篇
- 托管班二人合伙協(xié)議2025版3篇
- 2025年中國(guó)咖喱粉行業(yè)市場(chǎng)運(yùn)行現(xiàn)狀及投資戰(zhàn)略研究報(bào)告
- 餐廚垃圾收運(yùn)安全操作規(guī)范
- 皮膚內(nèi)科過(guò)敏反應(yīng)病例分析
- 電影《獅子王》的視聽語(yǔ)言解析
- 妊娠合并低鉀血癥護(hù)理查房
- 煤礦反三違培訓(xùn)課件
- 向流程設(shè)計(jì)要效率
- 2024年中國(guó)航空發(fā)動(dòng)機(jī)集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 當(dāng)代中外公司治理典型案例剖析(中科院研究生課件)
- 動(dòng)力管道設(shè)計(jì)手冊(cè)-第2版
- 2022年重慶市中考物理試卷A卷(附答案)
- Python繪圖庫(kù)Turtle詳解(含豐富示例)
評(píng)論
0/150
提交評(píng)論