《C++程序設(shè)計(jì)》課件-第4章_第1頁(yè)
《C++程序設(shè)計(jì)》課件-第4章_第2頁(yè)
《C++程序設(shè)計(jì)》課件-第4章_第3頁(yè)
《C++程序設(shè)計(jì)》課件-第4章_第4頁(yè)
《C++程序設(shè)計(jì)》課件-第4章_第5頁(yè)
已閱讀5頁(yè),還剩127頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

C++程序設(shè)計(jì)第4章繼承與組合1234繼承與派生的概念第4章繼承與組合本章學(xué)習(xí)要點(diǎn)派生類(lèi)的構(gòu)成派生類(lèi)的聲明方式派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性5678派生類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)第4章繼承與組合本章學(xué)習(xí)要點(diǎn)基類(lèi)與派生類(lèi)對(duì)象的關(guān)系多重繼承組合——對(duì)象組成對(duì)象本章學(xué)習(xí)目標(biāo)1.理解繼承和派生的概念;2.掌握派生類(lèi)的聲明方式,派生類(lèi)的構(gòu)成,派生類(lèi)對(duì)基類(lèi)的3種繼承方式;3.掌握派生類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行時(shí)機(jī);4.掌握多重繼承的聲明方法;多重繼承派生類(lèi)的構(gòu)造函數(shù)與析構(gòu)函數(shù)的定義及執(zhí)行;5.理解虛基類(lèi)的概念,掌握其作用和聲明方法;6.理解組合的概念,掌握繼承與組合在軟件開(kāi)發(fā)中的意義。第4章繼承與組合面向?qū)ο蠹夹g(shù)強(qiáng)調(diào)軟件的可重用性(softwarereusability)。C++語(yǔ)言提供了類(lèi)的繼承機(jī)制,解決了軟件重用問(wèn)題。

第4章繼承與組合在C++中,所謂“繼承”就是在一個(gè)或多個(gè)已存在的類(lèi)的基礎(chǔ)上建立一個(gè)新的類(lèi)。已存在的類(lèi)稱(chēng)為“基類(lèi)”、“父類(lèi)”或“一般類(lèi)”。新建立的類(lèi)稱(chēng)為“派生類(lèi)”、“子類(lèi)”或“特殊類(lèi)”。

4.1繼承與派生的概念第4章繼承與組合一個(gè)新類(lèi)從已有的類(lèi)那里獲得其已有特性,這種現(xiàn)象稱(chēng)為類(lèi)的繼承。通過(guò)繼承,一個(gè)新建子類(lèi)從已有的父類(lèi)那里獲得父類(lèi)的特性。從另一角度說(shuō),從已有的父類(lèi)產(chǎn)生一個(gè)新的子類(lèi),稱(chēng)為類(lèi)的派生。類(lèi)的繼承是用已有的類(lèi)來(lái)建立專(zhuān)用類(lèi)的編程技術(shù)。4.1繼承與派生的概念第4章繼承與組合派生類(lèi)繼承了基類(lèi)的所有數(shù)據(jù)成員和成員函數(shù)(不包括基類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)),并可以增加自己的新成員,同時(shí)也可以調(diào)整來(lái)自基類(lèi)的數(shù)據(jù)成員和成員函數(shù)。基類(lèi)和派生類(lèi)是相對(duì)而言的。一個(gè)基類(lèi)可以派生出多個(gè)派生類(lèi),每一個(gè)派生類(lèi)又可以作為基類(lèi)再派生出新的派生類(lèi)。一代一代地派生下去,就形成了類(lèi)的繼承層次結(jié)構(gòu),4.1繼承與派生的概念第4章繼承與組合圖4-1單繼承中學(xué)生學(xué)生初中生高中生專(zhuān)科生本科生研究生碩士生博士生大學(xué)生小學(xué)生留學(xué)生一個(gè)派生類(lèi)只從一個(gè)基類(lèi)派生,這稱(chēng)為單繼承(singleinheritance),這種繼承關(guān)系所形成的層次是一個(gè)樹(shù)形結(jié)構(gòu),可以用圖4-1表示。第4章繼承與組合圖4-2多繼承銷(xiāo)售經(jīng)理經(jīng)理工人銷(xiāo)售人員職員一個(gè)派生類(lèi)不僅可以從一個(gè)基類(lèi)派生,也可以從多個(gè)基類(lèi)派生。一個(gè)派生類(lèi)有兩個(gè)或多個(gè)基類(lèi)的稱(chēng)為多重繼承(multipleinheritance),這種繼承關(guān)系所形成的結(jié)構(gòu)如圖4-2所示。第4章繼承與組合基類(lèi)和派生類(lèi)的關(guān)系,可以表述為:

派生類(lèi)是基類(lèi)的具體化,而基類(lèi)是派生類(lèi)的抽象。4.1繼承與派生的概念第4章繼承與組合單繼承派生類(lèi)的聲明格式如下:class

派生類(lèi)名:[繼承方式]基類(lèi)名{

派生類(lèi)新增加的成員};其中,繼承方式可以是public(公用的)、private(私有的)、protected(受保護(hù)的)。此項(xiàng)是可選的,如果不寫(xiě)此項(xiàng),則默認(rèn)為private(私有的)。4.2派生類(lèi)的聲明方式第4章繼承與組合classBase

//聲明基類(lèi){public://基類(lèi)公用成員

voidsetx(intn){x=n;}intgetx(){returnx;}voidshowx(){cout<<"Baseclass:x="<<x<<endl;}private://基類(lèi)私有成員

intx;};第4章繼承與組合//以public方式聲明派生類(lèi)DerivedclassDerived:

publicBase{public:voidsety(intn){y=n;}intgety(){returny;}voidshowy()

{cout<<"Derivedclass:y="<<y<<endl;}private:inty;};第4章繼承與組合派生類(lèi)中的成員包括從基類(lèi)繼承過(guò)來(lái)的成員和自己新增加的成員兩大部分,從基類(lèi)繼承過(guò)來(lái)的成員體現(xiàn)了派生類(lèi)從基類(lèi)繼承而獲得的共性,而新增加的成員體現(xiàn)了派生類(lèi)的個(gè)性,體現(xiàn)了派生類(lèi)與基類(lèi)的不同,體現(xiàn)了不同派生類(lèi)的區(qū)別。4.3派生類(lèi)的構(gòu)成第4章繼承與組合第4章繼承與組合圖4-3基類(lèi)Base和派生類(lèi)Derived的成員示意圖

voidsetx();intgetx();voidshowx();

intx;Base類(lèi)

voidsetx();intgetx();voidshowx();intx;Derived類(lèi)

voidsety();intgety();voidshowy();inty;繼承新增數(shù)據(jù)成員成員函數(shù)實(shí)際上,并不是把基類(lèi)的成員和派生類(lèi)自己新增加的成員簡(jiǎn)單地加在一起就成為派生類(lèi)。構(gòu)造一個(gè)派生類(lèi)一般經(jīng)歷3個(gè)步驟:1.從基類(lèi)接收成員2.調(diào)整從基類(lèi)接收的成員3.增加新成員。4.3派生類(lèi)的構(gòu)成第4章繼承與組合派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性不僅與在聲明基類(lèi)時(shí)所聲明的訪(fǎng)問(wèn)屬性有關(guān),而且與在聲明派生類(lèi)時(shí)所指定的對(duì)基類(lèi)的繼承方式有關(guān),這兩個(gè)因素共同決定基類(lèi)成員在派生類(lèi)中的訪(fǎng)問(wèn)屬性。4.4派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性第4章繼承與組合派生類(lèi)對(duì)基類(lèi)的繼承方式有public,private和protected3種。不同的繼承方式?jīng)Q定了基類(lèi)成員在派生類(lèi)中的訪(fǎng)問(wèn)屬性。簡(jiǎn)單地說(shuō):(1)公用繼承(publicinheritance)基類(lèi)的公用成員和保護(hù)成員在派生類(lèi)中保持原有訪(fǎng)問(wèn)屬性,其私有成員仍為基類(lèi)私有。4.4派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性第4章繼承與組合(2)私有繼承(privateinheritance)基類(lèi)的公用成員和保護(hù)成員在派生類(lèi)中成了私有成員。其私有成員仍為基類(lèi)私有。4.4派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性第4章繼承與組合(3)受保護(hù)的繼承(protectedinheritance)基類(lèi)的公用成員和保護(hù)成員在派生類(lèi)中成了保護(hù)成員,其私有成員仍為基類(lèi)私有。

保護(hù)成員的意思是:不能被外界訪(fǎng)問(wèn),但可以被派生類(lèi)的成員訪(fǎng)問(wèn)。4.4派生類(lèi)中基類(lèi)成員的訪(fǎng)問(wèn)屬性第4章繼承與組合在聲明一個(gè)派生類(lèi)時(shí)將基類(lèi)的繼承方式指定為public的,稱(chēng)為公用繼承。用公用繼承方式建立的派生類(lèi)稱(chēng)為公用派生類(lèi)(publicderivedclass),其基類(lèi)稱(chēng)為公用基類(lèi)(publicbaseclass)。4.4.1公用繼承第4章繼承與組合4.4.1公用繼承第4章繼承與組合表4-1公用基類(lèi)成員在派生類(lèi)中的訪(fǎng)問(wèn)屬性公用基類(lèi)的成員在公用派生類(lèi)中的訪(fǎng)問(wèn)屬性私有成員不可訪(fǎng)問(wèn)公用成員公用保護(hù)成員保護(hù)第4章繼承與組合【例4-1】公用繼承的例子。

#include<iostream>usingnamespacestd;classBase//聲明基類(lèi){public:

//基類(lèi)公用成員voidsetx(intn){x=n;}intgetx(){returnx;}voidshowx(){cout<<"x="<<x<<endl;}private:

//基類(lèi)私有成員intx;};//以public方式聲明派生類(lèi)Derived

classDerived:publicBase{public:voidsety(intn){y=n;}intgety(){returny;}voidshowy(){cout<<"y="<<y<<endl;}voidset(intm,intn)

{

setx(m);//在Derived中x不可訪(fǎng)問(wèn)

y=n;}第4章繼承與組合

voidshow(){//cout<<"x="<<x<<endl;

cout<<"x="<<getx()<<endl;

//showx();

cout<<"y="<<y<<endl;

}private:inty;};第4章繼承與組合

intmain()

{

Derivedobj;

obj.setx(10);

obj.showx();

obj.sety(20);

obj.showy();

obj.set(30,40);

obj.show();

return0;

}第4章繼承與組合程序運(yùn)行結(jié)果如下:x=10y=20x=30y=40在聲明一個(gè)派生類(lèi)時(shí)將基類(lèi)的繼承方式指定為private的,稱(chēng)為私有繼承。用私有繼承方式建立的派生類(lèi)稱(chēng)為私有派生類(lèi)(privatederivedclass),其基類(lèi)稱(chēng)為私有基類(lèi)(privatebaseclass)。4.4.2私有繼承第4章繼承與組合4.4.2私有繼承第4章繼承與組合表4-2私有基類(lèi)成員在派生類(lèi)中的訪(fǎng)問(wèn)屬性私有基類(lèi)的成員在私有派生類(lèi)中的訪(fǎng)問(wèn)屬性私有成員不可訪(fǎng)問(wèn)公用成員私有保護(hù)成員私有第4章繼承與組合【例4-2】將【例4-1】中的公用繼承方式改為用私有繼承方式(基類(lèi)Base不變)。私有派生類(lèi)如下://以private方式聲明派生類(lèi)Derived

classDerived:privateBase{public:voidsety(intn){y=n;}intgety(){returny;}voidshowy()

{

cout<<"y="<<y<<endl;

}

第4章繼承與組合voidset(intm,intn)

{

setx(m);//在Derived中x不可訪(fǎng)問(wèn)

y=n;

}

voidshow()

{

//getx()

cout<<"x="<<getx()<<endl;

cout<<"y="<<y<<endl;

}private:inty;};

intmain()

{

Derivedobj;

//obj.setx(10);

//obj.showx();

obj.sety(20);

obj.showy();

obj.set(30,40);

obj.show();

return0;

}第4章繼承與組合程序運(yùn)行結(jié)果如下:y=20x=30y=40由protected聲明的成員稱(chēng)為“受保護(hù)的成員”,簡(jiǎn)稱(chēng)“保護(hù)成員”。從類(lèi)的用戶(hù)角度來(lái)看,保護(hù)成員等價(jià)于私有成員。但有一點(diǎn)與私有成員不同,保護(hù)成員可以被派生類(lèi)的成員函數(shù)訪(fǎng)問(wèn)。4.4.3保護(hù)成員和保護(hù)繼承第4章繼承與組合在定義一個(gè)派生類(lèi)時(shí)將基類(lèi)的繼承方式指定為protected的,稱(chēng)為保護(hù)繼承。用保護(hù)繼承方式建立的派生類(lèi)稱(chēng)為保護(hù)派生類(lèi)(protectedderivedclass),其基類(lèi)稱(chēng)為受保護(hù)的基類(lèi)(protectedbaseclass),簡(jiǎn)稱(chēng)保護(hù)基類(lèi)。4.4.3保護(hù)成員和保護(hù)繼承第4章繼承與組合第4章繼承與組合表4-3基類(lèi)成員在派生類(lèi)中的訪(fǎng)問(wèn)屬性4.4.3保護(hù)成員和保護(hù)繼承基類(lèi)中的成員在公用派生類(lèi)中的訪(fǎng)問(wèn)屬性在私有派生類(lèi)中的訪(fǎng)問(wèn)屬性在保護(hù)派生類(lèi)中的訪(fǎng)問(wèn)屬性私有成員不可訪(fǎng)問(wèn)不可訪(fǎng)問(wèn)不可訪(fǎng)問(wèn)公用成員公用私有保護(hù)保護(hù)成員保護(hù)私有保護(hù)通過(guò)以上的介紹,可以知道:(1)在派生類(lèi)中,成員有4種不同的訪(fǎng)問(wèn)屬性:①公用的:派生類(lèi)內(nèi)和派生類(lèi)外都可以訪(fǎng)問(wèn)。②受保護(hù)的:派生類(lèi)內(nèi)可以訪(fǎng)問(wèn),派生類(lèi)外不能訪(fǎng)問(wèn),其下一層的派生類(lèi)可以訪(fǎng)問(wèn)。③私有的:派生類(lèi)內(nèi)可以訪(fǎng)問(wèn),派生類(lèi)外不能訪(fǎng)問(wèn)。④不可訪(fǎng)問(wèn)的:派生類(lèi)內(nèi)和派生類(lèi)外都不能訪(fǎng)問(wèn)。4.4.3保護(hù)成員和保護(hù)繼承第4章繼承與組合第4章繼承與組合表4-4派生類(lèi)中的成員的訪(fǎng)問(wèn)屬性派生類(lèi)中的成員在派生類(lèi)中在派生類(lèi)外在下層公用派生類(lèi)中派生類(lèi)中訪(fǎng)問(wèn)屬性為公用的成員可以可以可以派生類(lèi)中訪(fǎng)問(wèn)屬性為受保護(hù)的成員可以不可以可以派生類(lèi)中訪(fǎng)問(wèn)屬性為私有的成員可以不可以不可以在派生類(lèi)中不可訪(fǎng)問(wèn)的成員不可以不可以不可以(2)類(lèi)的成員在不同作用域中有不同的訪(fǎng)問(wèn)屬性,對(duì)這一點(diǎn)要十分清楚。4.4.3保護(hù)成員和保護(hù)繼承第4章繼承與組合第4章繼承與組合【例4-3】保護(hù)繼承的例子。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi){public://基類(lèi)公用成員

voidsetx(intn){x=n;}voidshowx(){cout<<"x="<<x<<endl;}protected://基類(lèi)保護(hù)成員

intgetx(){returnx;}private://基類(lèi)私有成員

intx;};第4章繼承與組合//以protected方式聲明派生類(lèi)Derived

classDerived:protectedBase{public:voidsety(intn){y=n;}intgety(){returny;}voidshowy(){cout<<"y="<<y<<endl;}voidset(intm,intn){

setx(m);//在Derived中x不可訪(fǎng)問(wèn)

y=n;

}第4章繼承與組合

voidshow(){//getx()

cout<<"x="<<getx()<<endl;

cout<<"y="<<y<<endl;

}private:inty;};

intmain()

{

Derivedobj;

//obj.setx(10);

//obj.showx();

obj.sety(20);

obj.showy();

obj.set(30,40);

obj.show();

return0;

}第4章繼承與組合程序運(yùn)行結(jié)果如下:y=20x=30y=40在前面介紹派生類(lèi)的構(gòu)成時(shí)曾提到:可以在派生類(lèi)中聲明一個(gè)與基類(lèi)成員同名的成員,則派生類(lèi)的新成員會(huì)屏蔽與其同名的基類(lèi)成員,使同名的基類(lèi)成員成為“不可見(jiàn)”的,即基類(lèi)成員的名字被隱藏。4.4.4派生類(lèi)對(duì)基類(lèi)成員的重定義

和名字隱藏第4章繼承與組合第4章繼承與組合【例4-4】派生類(lèi)重定義基類(lèi)成員函數(shù)的例子。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi){public://基類(lèi)公用成員

voidset(intn){x=n;}voidshow(){cout<<"Baseclass:x="<<x<<endl;}private://基類(lèi)私有成員

intx;};第4章繼承與組合//以public方式聲明派生類(lèi)Derived

classDerived:publicBase{public:voidset(inti,intj){m=i;n=j;}voidset(inti,intj,intk){//L1訪(fǎng)問(wèn)從基類(lèi)繼承過(guò)來(lái)的同名成員函數(shù)set()

Base::set(i);//L1

m=j;n=k;}

第4章繼承與組合voidshow(){//L2訪(fǎng)問(wèn)從基類(lèi)繼承過(guò)來(lái)的同名成員函數(shù)show()Base::show();//L2

cout<<"Derivedclass:m="<<m<<endl;cout<<"Derivedclass:n="<<n<<endl;}private:intm,n;};

intmain(){Derivedobj;obj.set(1,2,3);

//L3obj.show();

//L4//obj.set(10);//L5錯(cuò)誤,只能是obj.Base::set(10);obj.Base::set(10);//L6正確obj.set(20,30);

//L7

obj.show();

//L8

obj.Base::show();

//L9return0;}第4章繼承與組合程序運(yùn)行結(jié)果如下:Baseclass:x=1Derivedclass:m=2Derivedclass:n=3Baseclass:x=10Derivedclass:m=20Derivedclass:n=30Baseclass:x=10從上例可以看出:(1)如果是在派生類(lèi)中聲明了一個(gè)與基類(lèi)成員函數(shù)名字相同,參數(shù)也相同的成員函數(shù),則基類(lèi)中的成員函數(shù)將被隱藏。(2)如果是在派生類(lèi)中聲明了一個(gè)與基類(lèi)成員函數(shù)名字相同,但參數(shù)不同的成員函數(shù),則基類(lèi)中的成員函數(shù)也將被隱藏。4.4.4派生類(lèi)對(duì)基類(lèi)成員的重定義和名字隱藏第4章繼承與組合第4章繼承與組合【例4-5】派生類(lèi)重定義基類(lèi)數(shù)據(jù)成員的例子。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi){public://基類(lèi)公用成員

floaty;voidset(intn){x=n;}voidshow(){cout<<"Baseclass:x="<<x<<endl;}private://基類(lèi)私有成員

intx;};第4章繼承與組合//以public方式聲明派生類(lèi)Derived

classDerived:publicBase{public:voidset(inti,intj,intk){Base::set(i);y=j;z=k;}voidshow(){Base::show();cout<<"Baseclass:y="<<Base::y<<endl;cout<<"Derivedclass:y="<<y<<endl;cout<<"Derivedclass:z="<<z<<endl;}private:inty,z;};

intmain()

{Derivedobj;

obj.set(1,2,3);

obj.Base::y=12.3;

obj.show();

return0;

}第4章繼承與組合程序運(yùn)行結(jié)果如下:Baseclass:x=1Baseclass:y=12.3Derivedclass:y=2Derivedclass:z=3由于基類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類(lèi)是不能繼承的。在聲明派生類(lèi)時(shí),一般還應(yīng)當(dāng)自己定義派生類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)。4.5派生類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)第4章繼承與組合構(gòu)造函數(shù)的作用是在創(chuàng)建對(duì)象時(shí)對(duì)對(duì)象的數(shù)據(jù)成員進(jìn)行初始化。派生類(lèi)數(shù)據(jù)成員包括從基類(lèi)繼承過(guò)來(lái)的數(shù)據(jù)成員和自己新增加的數(shù)據(jù)成員,在設(shè)計(jì)派生類(lèi)的構(gòu)造函數(shù)時(shí),不僅要考慮派生類(lèi)新增數(shù)據(jù)成員的初始化,還應(yīng)當(dāng)考慮對(duì)其從基類(lèi)繼承過(guò)來(lái)的數(shù)據(jù)成員的初始化。采取的方法是在執(zhí)行派生類(lèi)的構(gòu)造函數(shù)時(shí),調(diào)用基類(lèi)的構(gòu)造函數(shù)。4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合下面從最簡(jiǎn)單的派生類(lèi)構(gòu)造函數(shù)的定義說(shuō)起。所謂簡(jiǎn)單的派生類(lèi)是指只有一個(gè)基類(lèi),而且只有一級(jí)派生,在派生類(lèi)的數(shù)據(jù)成員中不包含其他類(lèi)對(duì)象的派生類(lèi)。簡(jiǎn)單的派生類(lèi)構(gòu)造函數(shù)的定義請(qǐng)看下面這個(gè)例子:4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合第4章繼承與組合【例4-6】簡(jiǎn)單派生類(lèi)的構(gòu)造函數(shù)。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi)Base{public:Base(intm,intn){x=m;y=n;}//基類(lèi)構(gòu)造函數(shù)~Base(){}//基類(lèi)析構(gòu)函數(shù)protected://保護(hù)部分

intx;inty;};第4章繼承與組合classDerived:publicBase//聲明公用派生類(lèi)Derived{public://派生類(lèi)的共用部分

Derived(intm,intn,intk):Base(m,n)

{z=k;}

voidshow(){cout<<"x="<<x<<endl;cout<<"y="<<y<<endl;cout<<"z="<<z<<endl;}~Derived(){}//派生類(lèi)的析構(gòu)函數(shù)private://派生類(lèi)的私有部分intz;};intmain(){Derivedobj(12,34,56);

obj.show();//輸出結(jié)果

return0;}第4章繼承與組合程序運(yùn)行結(jié)果如下:x=12y=34z=56上例中派生類(lèi)Derived的構(gòu)造函數(shù)有3個(gè)形參,前2個(gè)作為調(diào)用基類(lèi)構(gòu)造函數(shù)的實(shí)參,第3個(gè)為對(duì)派生類(lèi)新增數(shù)據(jù)成員z初始化所需要的參數(shù)。其關(guān)系如圖4-4所示。4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合Derived(intm,intn,intk):Base(m,n)圖4-4派生類(lèi)Derived的構(gòu)造函數(shù)的參數(shù)傳遞定義簡(jiǎn)單派生類(lèi)構(gòu)造函數(shù)的一般形式為:<派生類(lèi)構(gòu)造函數(shù)名>(<總參數(shù)列表>):<基類(lèi)構(gòu)造函數(shù)名>(<參數(shù)表>){<派生類(lèi)新增數(shù)據(jù)成員初始化>};4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合在建立一個(gè)對(duì)象時(shí),執(zhí)行構(gòu)造函數(shù)的順序是:(1)最先調(diào)用基類(lèi)的構(gòu)造函數(shù),對(duì)基類(lèi)數(shù)據(jù)成員初始化。(2)再執(zhí)行派生類(lèi)構(gòu)造函數(shù)的函數(shù)體,對(duì)派生類(lèi)新增數(shù)據(jù)成員初始化。4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合在使用派生類(lèi)構(gòu)造函數(shù)時(shí),還有以下幾種情況:(1)多級(jí)派生的構(gòu)造函數(shù)。一個(gè)類(lèi)不僅可以派生出一個(gè)派生類(lèi),派生類(lèi)還可以繼續(xù)派生,形成派生的層次結(jié)構(gòu)。在派生的層次結(jié)構(gòu)中,每一層派生類(lèi)的構(gòu)造函數(shù)只負(fù)責(zé)調(diào)用其上一層(即它的直接基類(lèi))的構(gòu)造函數(shù)。若在【例4-6】的基礎(chǔ)上由派生類(lèi)Derived再派生出派生類(lèi)IndirectDerived,則派生類(lèi)IndirectDerived的定義如下:4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合classIndirectDerived:publicDerived{public:IndirectDerived(intm,intn,intk,int):Derived(m,n,k){w=p;}voidshow(){Derived::show();cout<<"w="<<w<<endl;}private:intw;};4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合(2)當(dāng)不需要對(duì)派生類(lèi)新增的成員進(jìn)行任何初始化操作時(shí),派生類(lèi)構(gòu)造函數(shù)的函數(shù)體可以為空,即構(gòu)造函數(shù)是空函數(shù),如【例4-6】中派生類(lèi)Derived的構(gòu)造函數(shù)可以改寫(xiě)為:

Derived(intm,intn,intk):Base(m,n){}此派生類(lèi)構(gòu)造函數(shù)的作用只是為了將參數(shù)傳遞給基類(lèi)構(gòu)造函數(shù),并在執(zhí)行派生類(lèi)構(gòu)造函數(shù)時(shí)調(diào)用基類(lèi)構(gòu)造函數(shù)。4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合(3)如果基類(lèi)中沒(méi)有定義構(gòu)造函數(shù),或定義了沒(méi)有參數(shù)的構(gòu)造函數(shù),那么在定義派生類(lèi)構(gòu)造函數(shù)時(shí)可以不寫(xiě)基類(lèi)構(gòu)造函數(shù)。在調(diào)用派生類(lèi)構(gòu)造函數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用基類(lèi)的默認(rèn)構(gòu)造函數(shù)。如果在基類(lèi)中既定義了無(wú)參的構(gòu)造函數(shù),又定義了有參的構(gòu)造函數(shù)(構(gòu)造函數(shù)的重載),則在定義派生類(lèi)構(gòu)造函數(shù)時(shí),既可以包含基類(lèi)構(gòu)造函數(shù)及其參數(shù),亦可以不包含基類(lèi)構(gòu)造函數(shù)。在調(diào)用派生類(lèi)構(gòu)造函數(shù)時(shí),根據(jù)構(gòu)造函數(shù)的內(nèi)容決定調(diào)用基類(lèi)的有參的構(gòu)造函數(shù)還是無(wú)參的構(gòu)造函數(shù)。我們可以根據(jù)派生類(lèi)的需要決定采用哪一種方式。4.5.1派生類(lèi)構(gòu)造函數(shù)第4章繼承與組合和構(gòu)造函數(shù)一樣,基類(lèi)的析構(gòu)函數(shù)派生類(lèi)也不能繼承。在聲明派生類(lèi)時(shí),可以根據(jù)需要定義自己的析構(gòu)函數(shù),用來(lái)對(duì)派生類(lèi)中新增加的成員進(jìn)行清理工作。在執(zhí)行派生類(lèi)的析構(gòu)函數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)函數(shù),對(duì)基類(lèi)進(jìn)行清理。派生類(lèi)析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)正好相反:(1)最先執(zhí)行派生類(lèi)的析構(gòu)函數(shù)的函數(shù)體,對(duì)派生類(lèi)新增加的成員進(jìn)行清理。(2)再調(diào)用基類(lèi)的析構(gòu)函數(shù),對(duì)基類(lèi)進(jìn)行清理。4.5.2派生類(lèi)析構(gòu)函數(shù)第4章繼承與組合第4章繼承與組合【例4-7】派生類(lèi)的析構(gòu)函數(shù)。#include<iostream>usingnamespacestd;classBase{public:Base(){cout<<"BaseConstructor"<<endl;}~Base(){cout<<"BaseDestructor"<<endl;}};第4章繼承與組合classDerived:publicBase{public:Derived(){cout<<"DerivedConstructor"<<endl;}~Derived(){cout<<"DerivedDestructor"<<endl;}};intmain(){Derivedobj;return0;}程序運(yùn)行結(jié)果如下:BaseConstructorDerivedConstructorDerivedDestructorBaseDestructor多重繼承(multipleinheritance,MI)是指派生類(lèi)具有兩個(gè)或兩個(gè)以上的直接基類(lèi)(directclass)。4.6多重繼承第4章繼承與組合多重繼承可以看做是單繼承的擴(kuò)展,派生類(lèi)和每個(gè)基類(lèi)之間的關(guān)系可以看做是一個(gè)單繼承。多重繼承派生類(lèi)的聲明格式如下:class<派生類(lèi)名>:<繼承方式><基類(lèi)名1>,…,<繼承方式><基類(lèi)名n>{<派生類(lèi)新增加成員>};其中不同的基類(lèi)可以選擇不同的繼承方式。4.6.1聲明多重繼承的方法第4章繼承與組合在多重繼承方式下,定義派生類(lèi)構(gòu)造函數(shù)的一般形式如下:<派生類(lèi)名>(<總參數(shù)列表>):<基類(lèi)名1>(<參數(shù)表1>),…,<基類(lèi)名n>(<參數(shù)表n>){<派生類(lèi)新增數(shù)據(jù)成員的初始化>};其中,<總參數(shù)表>必須包含完成所有基類(lèi)數(shù)據(jù)成員初始化所需的參數(shù)。4.6.2多重繼承派生類(lèi)的構(gòu)造函數(shù)與析構(gòu)函數(shù)第4章繼承與組合在建立一個(gè)派生類(lèi)對(duì)象時(shí),構(gòu)造函數(shù)調(diào)用順序?yàn)椋合日{(diào)用所有基類(lèi)的構(gòu)造函數(shù),再執(zhí)行派生類(lèi)構(gòu)造函數(shù)的函數(shù)體。所有基類(lèi)構(gòu)造函數(shù)的調(diào)用順序?qū)凑账鼈冊(cè)诶^承方式中的聲明次序調(diào)用,而不是按派生類(lèi)構(gòu)造函數(shù)參數(shù)初始化列表中的次序調(diào)用。4.6.2多重繼承派生類(lèi)的構(gòu)造函數(shù)與析構(gòu)函數(shù)第4章繼承與組合第4章繼承與組合【例4-8】多重繼承派生類(lèi)的構(gòu)造函數(shù)。#include<iostream>usingnamespacestd;classBase1//聲明基類(lèi)Base{public://公用部分Base1(intm,intn){x=m;y=n;}//基類(lèi)構(gòu)造函數(shù)voidshow1()//成員函數(shù),輸出基類(lèi)數(shù)據(jù)成員{cout<<"x="<<x<<"y="<<y<<endl;}protected://保護(hù)部分

intx;inty;};第4章繼承與組合classBase2//聲明基類(lèi)Base2{public://公用部分

Base2(inti,intj){u=i;v=j;}//基類(lèi)構(gòu)造函數(shù)voidshow2()//成員函數(shù),輸出基類(lèi)數(shù)據(jù)成員{cout<<"u="<<u<<"v="<<v<<endl;}protected://保護(hù)部分

intu;intv;};第4章繼承與組合classDerived:publicBase1,publicBase2{public:Derived(inta,intb,intc,intd,inte):Base1(a,b),Base2(c,d),w(e){}voidshow(){cout<<"x="<<x<<"y="<<y;cout<<"u="<<u<<"v="<<v;cout<<"w="<<w<<endl;}private:intw;};第4章繼承與組合intmain(){Derivedobj(1,2,3,4,5);obj.show();return0;}程序運(yùn)行結(jié)果如下:x=1y=2u=3v=4w=5在派生類(lèi)的析構(gòu)函數(shù)問(wèn)題上,多重繼承方式也與單繼承方式類(lèi)似。派生類(lèi)析構(gòu)函數(shù)的執(zhí)行順序與其構(gòu)造函數(shù)執(zhí)行順序正好相反,首先執(zhí)行派生類(lèi)析構(gòu)函數(shù)的函數(shù)體,對(duì)派生類(lèi)新增的數(shù)據(jù)成員進(jìn)行清理;然后調(diào)用基類(lèi)的析構(gòu)函數(shù),對(duì)從基類(lèi)繼承來(lái)的成員進(jìn)行清理。所有基類(lèi)的析構(gòu)函數(shù)將按照它們?cè)诶^承方式中的聲明次序的逆序、從右到左調(diào)用。4.6.2多重繼承派生類(lèi)的構(gòu)造函數(shù)與析構(gòu)函數(shù)第4章繼承與組合在多重繼承方式下,派生類(lèi)繼承了多個(gè)基類(lèi)的成員。如果在這多個(gè)基類(lèi)中擁有同名的成員,那么,派生類(lèi)在繼承各個(gè)基類(lèi)的成員之后,當(dāng)調(diào)用該派生類(lèi)的這些同名成員時(shí),由于成員標(biāo)識(shí)符不唯一,出現(xiàn)二義性,編譯器無(wú)法確定到底應(yīng)該選擇派生類(lèi)中的哪一個(gè)成員,這種由于多重繼承而引起的對(duì)派生類(lèi)的某個(gè)成員訪(fǎng)問(wèn)出現(xiàn)不唯一的情況就稱(chēng)為二義性問(wèn)題。4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合二義性主要分為3種類(lèi)型:(1)兩個(gè)基類(lèi)有同名成員;(2)兩個(gè)基類(lèi)和派生類(lèi)三者都有同名成員;(3)如果兩個(gè)基類(lèi)Base1和Base2是從同一個(gè)基類(lèi)Base派生的。4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合第4章繼承與組合(1)兩個(gè)基類(lèi)有同名成員#include<iostream>usingnamespacestd;classBase1//聲明基類(lèi)Base1{public://公用部分

intx;voiddisplay(){cout<<"Base1::x="<<x<<endl;}};classBase2//聲明基類(lèi)Base2{public://公用部分

intx;voiddisplay(){cout<<"Base2::x="<<x<<endl;}};第4章繼承與組合classDerived:publicBase1,publicBase2{public:inty;voidshow(){cout<<"Base1::x="<<Base1::x<<endl

//Base1::display();

cout<<"Base2::x="<<Base2::x<<endl;

//Base2::display();out<<"Derived::y="<<y<<endl;

}};第4章繼承與組合intmain(){Derivedobj;obj.x=8;//錯(cuò)誤

obj.display();//錯(cuò)誤return0;}編譯此程序,出現(xiàn)如下錯(cuò)誤和警告提示:errorC2385:'Derived::x'isambiguouswarningC4385:couldbethe'x'inbase'Base1'ofclass'Derived'warningC4385:orthe'x'inbase'Base2'ofclass'Derived'errorC2385:'Derived::display'isambiguouswarningC4385:couldbethe'display'inbase'Base1'ofclass'Derived'warningC4385:orthe'display'inbase'Base2'ofclass'Derived'4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合由于基類(lèi)Base1和Base2都有數(shù)據(jù)成員x和成員函數(shù)display(),編譯系統(tǒng)無(wú)法識(shí)別要訪(fǎng)問(wèn)的是哪一個(gè)基類(lèi)的成員,因此程序編譯出錯(cuò)。解決此類(lèi)問(wèn)題可以用基類(lèi)名來(lái)限定,即寫(xiě)成:obj.Base1::x=3;

obj.Base1::display();

4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合如果是在派生類(lèi)Derived中通過(guò)派生類(lèi)成員函數(shù)show()訪(fǎng)問(wèn)基類(lèi)Base1的x和display()成員,可以不必寫(xiě)對(duì)象名而直接寫(xiě):cout<<"Base1::x="<<Base1::x<<endl;Base1::display();

//該句與上一句的作用相同4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合(2)兩個(gè)基類(lèi)和派生類(lèi)三者都有同名成員4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合如將上面的Derived類(lèi)改為:第4章繼承與組合classDerived:publicBase1,publicBase2{public:intx;voiddisplay(){cout<<"Base1::x="<<Base1::x<<endl;//Base1::display();cout<<"Base2::x="<<Base2::x<<endl;//Base2::display();cout<<"Derived::x="<<x<<endl;

}};此時(shí),如果在main函數(shù)中用派生類(lèi)Derived定義一個(gè)對(duì)象obj,并調(diào)用其數(shù)據(jù)成員x和成員函數(shù)display(),obj.x=8;

//正確,訪(fǎng)問(wèn)派生類(lèi)的x成員obj.display();

//正確,訪(fǎng)問(wèn)派生類(lèi)的display()成員程序能正常編譯,也能正常運(yùn)行。此時(shí)它訪(fǎng)問(wèn)的是派生類(lèi)Derived中的成員。規(guī)則是:基類(lèi)的同名成員在派生類(lèi)中被屏蔽,成為“不可見(jiàn)”的,即基類(lèi)成員的名字被隱藏。4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合(3)如果兩個(gè)基類(lèi)Base1和Base2是從同一個(gè)基類(lèi)Base派生的4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合classBase//聲明基類(lèi)Base{public://公用部分

intx;voiddisplay(){cout<<"Base::x="<<x<<endl;}};第4章繼承與組合classBase1:publicBase//聲明派生類(lèi)Base1{public://公用部分

inty;};classBase2:publicBase//聲明派生類(lèi)Base2{public://公用部分

intz;};第4章繼承與組合classDerived:publicBase1,publicBase2{public:intw;voidshow(){Base1::display();//或者Base2::display();cout<<"Base1::y="<<y<<endl;cout<<"Base1::z="<<z<<endl;cout<<"Derived::w="<<w<<endl;}};間接派生類(lèi)Derived中的情況如圖4-5所示。第4章繼承與組合intBase1::x;intBase1::y;intBase2::x;intBase2::z;intw;voidBase1::display();voidBase2::display();voidshow();Derived類(lèi)派生類(lèi)Derived的數(shù)據(jù)成員派生類(lèi)Derived的成員函數(shù)圖4-5間接派生類(lèi)Derived中的成員

間接派生類(lèi)Derived中的情況如圖4-5所示。第4章繼承與組合圖4-5間接派生類(lèi)Derived中的成員

基類(lèi)Base的成員派生類(lèi)Base1新增成員基類(lèi)Base的成員派生類(lèi)Base2新增成員派生類(lèi)Derived新增成員BaseBaseBase1Base2Derived如果在main函數(shù)中用派生類(lèi)Derived定義一個(gè)對(duì)象obj,并調(diào)用其數(shù)據(jù)成員x和成員函數(shù)display(),不能直接用:obj.x;obj.display();或obj.Base::x;obj.Base::display();應(yīng)當(dāng)通過(guò)類(lèi)Base的直接派生類(lèi)名來(lái)指出要訪(fǎng)問(wèn)的類(lèi)Base的哪一個(gè)派生類(lèi)中的基類(lèi)成員。如:obj.Base1::x=3;obj.Base1::display();4.6.3多重繼承引起的二義性問(wèn)題第4章繼承與組合1.虛基類(lèi)的作用從上節(jié)的介紹可知,如果一個(gè)派生類(lèi)有多個(gè)直接基類(lèi),而這些直接基類(lèi)又有一個(gè)共同的基類(lèi),則在最終的派生類(lèi)中會(huì)保留該間接共同基類(lèi)成員的多份同名成員。這種情況有時(shí)是必要的,但是由于保留間接共同基類(lèi)的多份成員,不僅占用較多的存儲(chǔ)空間,還增加了訪(fǎng)問(wèn)這些成員時(shí)的困難,容易出錯(cuò)。為了解決這個(gè)問(wèn)題,C++提供了虛基類(lèi)(virtualbaseclass)的方法,使得在繼承間接共同基類(lèi)時(shí)只保留其一份成員。4.6.4虛基類(lèi)第4章繼承與組合現(xiàn)在將上節(jié)的類(lèi)Base聲明為虛基類(lèi),形式如下:4.6.4虛基類(lèi)第4章繼承與組合classBase{…};classBase1:virtualpublicBase{…};classBase2:virtualpublicBase{…};注意:虛基類(lèi)并不是在聲明基類(lèi)時(shí)聲明的,而是在聲明派生類(lèi)時(shí),指定繼承方式時(shí)聲明的。因?yàn)橐粋€(gè)基類(lèi)可以在派生一個(gè)派生類(lèi)時(shí)作為虛基類(lèi),而在派生另一個(gè)派生類(lèi)時(shí)不作為虛基類(lèi)。聲明虛基類(lèi)的一般形式為:

class派生類(lèi)名:virtual繼承方式基類(lèi)名第4章繼承與組合4.6.4虛基類(lèi)第4章繼承與組合圖4-6虛擬繼承派生類(lèi)Derived中的成員

intx;voiddisplay();Base類(lèi)intx;voiddisplay();Base1類(lèi)inty;intx;voiddisplay();Base2類(lèi)intz;Derived類(lèi)intx;inty;intz;voiddisplay();intw;voidshow();從基類(lèi)繼承的成員派生類(lèi)Derived增加的成員virtualvirtual需要注意:為了保證虛基類(lèi)在派生類(lèi)中只繼承一次,應(yīng)當(dāng)在該基類(lèi)的所有直接派生類(lèi)中都把基類(lèi)聲明為虛基類(lèi)。否則仍然會(huì)出現(xiàn)對(duì)基類(lèi)的多次繼承。如果如圖4-7所示的那樣,在派生類(lèi)B和C中將類(lèi)A聲明為虛基類(lèi),而在派生類(lèi)D中沒(méi)有將類(lèi)A聲明為虛基類(lèi),則在派生類(lèi)E中,雖然從類(lèi)B和C路徑派生的部分只保留一份基類(lèi)成員,但從類(lèi)D路徑派生的部分還保留一份基類(lèi)成員。第4章繼承與組合4.6.4虛基類(lèi)第4章繼承與組合圖4-7多重繼承與虛基類(lèi)ABCDEvirtualvirtual4.6.4虛基類(lèi)2.虛基類(lèi)的初始化如果在虛基類(lèi)中定義了帶參數(shù)的構(gòu)造函數(shù),而且沒(méi)有定義默認(rèn)構(gòu)造函數(shù),則在其所有派生類(lèi)(包括直接派生或間接派生的派生類(lèi))中,都要通過(guò)構(gòu)造函數(shù)的初始化表對(duì)虛基類(lèi)進(jìn)行初始化。4.6.4虛基類(lèi)第4章繼承與組合第4章繼承與組合【例4-9】虛基類(lèi)的初始化。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi)Base{public://公用部分

Base(intm,intn):x(m),y(n){}//基類(lèi)構(gòu)造函數(shù)protected://保護(hù)部分

intx,y;};第4章繼承與組合classBase1:virtualpublicBase{public:Base1(intm,intn,intk):Base(m,n){z1=k;}protected:

intz1;};classBase2:virtualpublicBase{public:Base2(intm,intn,intp):Base(m,n){z2=p;}protected:

intz2;};第4章繼承與組合classDerived:publicBase1,publicBase2{public:Derived(intm,intn,into,intp,intq):Base(m,n),Base1(m,n,o),Base2(m,n,p){z=q;}voidshow(){cout<<"x="<<x<<endl;cout<<"y="<<y<<endl;cout<<"z1="<<z1<<endl;cout<<"z2="<<z2<<endl;cout<<"z="<<z<<endl;}protected:

intz;};第4章繼承與組合intmain(){Derivedobj(12,13,14,15,16);obj.show();return0;}程序運(yùn)行結(jié)果如下:x=12y=13z1=14z2=15z=16派生類(lèi)構(gòu)造函數(shù)調(diào)用的次序有3個(gè)原則:(1)同一層中對(duì)虛基類(lèi)構(gòu)造函數(shù)的調(diào)用優(yōu)先于對(duì)非虛基類(lèi)構(gòu)造函數(shù)的調(diào)用。(2)若同一層次中包含多個(gè)虛基類(lèi),則這些虛基類(lèi)的構(gòu)造函數(shù)按照它們?cè)诶^承方式中的聲明次序調(diào)用。(3)若虛基類(lèi)由非虛基類(lèi)派生出來(lái),則仍然先調(diào)用基類(lèi)構(gòu)造函數(shù),再按派生類(lèi)中構(gòu)造函數(shù)的執(zhí)行順序調(diào)用。4.6.4虛基類(lèi)第4章繼承與組合派生類(lèi)的析構(gòu)函數(shù)調(diào)用的次序與構(gòu)造函數(shù)的正好相反。如果存在虛基類(lèi)時(shí),在析構(gòu)函數(shù)的調(diào)用過(guò)程中,同一層對(duì)普通基類(lèi)析構(gòu)函數(shù)的調(diào)用總是優(yōu)先4.6.4虛基類(lèi)第4章繼承與組合通過(guò)前面的學(xué)習(xí)可以發(fā)現(xiàn):3種繼承方式中,只有公用繼承能夠較好的保留基類(lèi)的特征,它保留了除構(gòu)造函數(shù)、析構(gòu)函數(shù)以外的基類(lèi)所有成員,基類(lèi)的公用或保護(hù)成員的訪(fǎng)問(wèn)權(quán)限在派生類(lèi)中都按原樣保留了下來(lái),在派生類(lèi)外可以通過(guò)派生類(lèi)對(duì)象名調(diào)用基類(lèi)的公用成員函數(shù)訪(fǎng)問(wèn)基類(lèi)的私有成員。因此,公用派生類(lèi)具有基類(lèi)的全部功能,所有基類(lèi)能夠?qū)崿F(xiàn)的功能,公用派生類(lèi)都能實(shí)現(xiàn)。而非公用派生類(lèi)(私有或保護(hù)派生類(lèi))不能實(shí)現(xiàn)基類(lèi)的全部功能。因此,基類(lèi)對(duì)象與公用派生類(lèi)對(duì)象之間有賦值兼容關(guān)系。4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合基類(lèi)對(duì)象與公用派生類(lèi)對(duì)象之間的賦值兼容關(guān)系具體表現(xiàn)在以下3個(gè)方面:(1)公用派生類(lèi)對(duì)象可以向基類(lèi)對(duì)象賦值(2)公用派生類(lèi)對(duì)象可以代替基類(lèi)對(duì)象向基類(lèi)對(duì)象的引用進(jìn)行賦值或初始化(3)如果函數(shù)的參數(shù)是基類(lèi)對(duì)象或基類(lèi)對(duì)象的引用,相應(yīng)的實(shí)參可以使用公用派生類(lèi)對(duì)象(4)公用派生類(lèi)對(duì)象的地址可以賦給指向基類(lèi)對(duì)象的指針變量4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合(1)公用派生類(lèi)對(duì)象可以向基類(lèi)對(duì)象賦值Baseobj1(12,13);Derivedobj2(21,22,23);obj1=obj2;4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合這樣的賦值是允許的,在賦值時(shí)舍棄派生類(lèi)自己的成員,如圖4-8所示。4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合圖4-8派生類(lèi)對(duì)象向基類(lèi)賦值基類(lèi)數(shù)據(jù)成員基類(lèi)成員函數(shù)基類(lèi)基類(lèi)數(shù)據(jù)成員基類(lèi)成員函數(shù)派生類(lèi)派生類(lèi)數(shù)據(jù)成員派生類(lèi)成員函數(shù)賦值時(shí)此部分舍去不用(2)公用派生類(lèi)對(duì)象可以代替基類(lèi)對(duì)象向基類(lèi)對(duì)象的引用進(jìn)行賦值或初始化Baseobj1(12,13);Derivedobj2(21,22,23);Base&objref=obj1;

Base&objref=obj2;

objref=obj2;4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合需要說(shuō)明的是,此時(shí)objref并不是obj2的別名,也不與obj2共享同一段存儲(chǔ)單元。它只是obj2中基類(lèi)部分的別名,objref與obj2中基類(lèi)部分共享同一段存儲(chǔ)單元,objref與obj2具有相同的起始地址,如圖4-9所示。4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合圖4-9派生類(lèi)對(duì)基類(lèi)對(duì)象的引用賦值派生類(lèi)新增加的部分Obj2對(duì)象objref從基類(lèi)繼承的部分(3)如果函數(shù)的參數(shù)是基類(lèi)對(duì)象或基類(lèi)對(duì)象的引用,相應(yīng)的實(shí)參可以使用公用派生類(lèi)對(duì)象如有一函數(shù)show()如下:voidshow(Base&objref){cout<<objref.x<<endl;}則在調(diào)用函數(shù)show()時(shí)可以用基類(lèi)Base的公用派生類(lèi)對(duì)象作為實(shí)參,即:Derivedobj2(21,22,23);show(obj2);4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合(4)公用派生類(lèi)對(duì)象的地址可以賦給指向基類(lèi)對(duì)象的指針變量也就是說(shuō),指向基類(lèi)對(duì)象的指針也可以指向公用派生類(lèi)對(duì)象。但是通過(guò)指向基類(lèi)對(duì)象的指針只能訪(fǎng)問(wèn)公用派生類(lèi)對(duì)象中的基類(lèi)成員,而不能訪(fǎng)問(wèn)公用派生類(lèi)對(duì)象新增加的成員。4.7基類(lèi)與派生類(lèi)對(duì)象的關(guān)系第4章繼承與組合第4章繼承與組合【例4-10】基類(lèi)對(duì)象的指針指向公用派生類(lèi)對(duì)象的應(yīng)用。#include<iostream>usingnamespacestd;classBase//聲明基類(lèi){public://公用部分

Base(intm,intn):x(m),y(n){}//基類(lèi)構(gòu)造函數(shù)voidshow(){cout<<"x="<<x<<endl<<"y="<<y<<endl;}protected://保護(hù)部分

intx,y;};第4章繼承與組合classDerived:publicBase//聲明公用派生類(lèi)Derived{public:Derived(intm,intn,intk):Base(m,n){z=k;}voidshow(){cout<<"x="<<x<<endl;//輸出xcout<<"y="<<y<<endl;//輸出ycout<<"z="<<z<<endl;//輸出z}private://派生類(lèi)的私有數(shù)據(jù)

intz;};第4章繼承與組合intmai

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論