C++面向?qū)ο蟪绦蛟O(shè)計(jì)第5章_第1頁(yè)
C++面向?qū)ο蟪绦蛟O(shè)計(jì)第5章_第2頁(yè)
C++面向?qū)ο蟪绦蛟O(shè)計(jì)第5章_第3頁(yè)
C++面向?qū)ο蟪绦蛟O(shè)計(jì)第5章_第4頁(yè)
C++面向?qū)ο蟪绦蛟O(shè)計(jì)第5章_第5頁(yè)
已閱讀5頁(yè),還剩53頁(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)介

1第五章繼承和派生類(lèi)2繼承性是面向?qū)ο蟪绦蛟O(shè)計(jì)中最重要的機(jī)制。這種機(jī)制提供了無(wú)限重復(fù)利用程序資源的一種途徑。通過(guò)C++語(yǔ)言中的繼承機(jī)制,可以擴(kuò)充和完善舊的程序設(shè)計(jì)以適應(yīng)新的需求。這樣不僅可以節(jié)省程序開(kāi)發(fā)的時(shí)間和資源,并且為未來(lái)程序增添了新的資源。5.1派生和繼承的相關(guān)概念和作用3classStudent{intnum;charname[30];charsex;public:voiddisplay()//對(duì)成員函數(shù)display的定義

{cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}};5.1派生和繼承的相關(guān)概念和作用4classStudend1{intnum;//此行原來(lái)己有

charname[20];//此行原來(lái)己有

charsex;//此行原來(lái)己有

intage;charaddr[20];public:voiddisplay();//此行原來(lái)己有

{cout<<"num:"<<num<<endl;//此行原來(lái)己有

cout<<"name:"<<name<<endl;//此行原來(lái)己有

cout<<"sex:"<<sex<<endl;//此行原來(lái)己有

cout<<"age:"<<age<<endl;cout<<"address:"<<addr<<endl;}};5.1派生和繼承的相關(guān)概念和作用5利用原來(lái)定義的類(lèi)Student作為基礎(chǔ),再加上新的內(nèi)容即可,以減少重復(fù)的工作量。C++提供的繼承機(jī)制就是為了解決這個(gè)問(wèn)題。

在C++中所謂“繼承”就是在一個(gè)已存在的類(lèi)的基礎(chǔ)上建立一個(gè)新的類(lèi)。已存在的類(lèi)稱(chēng)為“基類(lèi)(baseclass)”或“父類(lèi)(fatherclass)”。新建立的類(lèi)稱(chēng)為“派生類(lèi)(derivedclass)”或“子類(lèi)(sonclass)”。5.1派生和繼承的相關(guān)概念和作用6classStudent1:publicStudent//聲明基類(lèi)是Student{private:

intage;//新增加的數(shù)據(jù)成員

stringaddr;//新增加的數(shù)據(jù)成員public:

voiddisplay_1()//新增加的成員函數(shù)

{cout<<"age:"<<age<<endl;cout<<"address:"<<addr<<endl;}};5.1派生和繼承的相關(guān)概念和作用7類(lèi)A派生類(lèi)B:類(lèi)A為基類(lèi),類(lèi)B為派生類(lèi)。AB新增加的成員數(shù)據(jù)和成員函數(shù)5.1派生和繼承的相關(guān)概念和作用8在C++語(yǔ)言中,一個(gè)派生類(lèi)可以從一個(gè)基類(lèi)派生,也可以從多個(gè)基類(lèi)派生。從一個(gè)基類(lèi)派生的繼承稱(chēng)為單繼承;從二個(gè)或多個(gè)基類(lèi)派生的繼承稱(chēng)為多重繼承。通過(guò)繼承機(jī)制,可以利用已有的數(shù)據(jù)類(lèi)型來(lái)定義新的數(shù)據(jù)類(lèi)型。所定義的新的數(shù)據(jù)類(lèi)型不僅擁有新定義的成員,而且還同時(shí)擁有舊的成員。5.1派生和繼承的相關(guān)概念和作用9在建立派生類(lèi)的過(guò)程中,基類(lèi)不會(huì)做任何改變;派生類(lèi)則除了繼承基類(lèi)的所有可引用的成員變量和成員函數(shù)外,還可另外定義本身的成員變量和處理這些變量的函數(shù)由于派生類(lèi)可繼承基類(lèi)的成員變量和成員函數(shù),因此在基類(lèi)中定義好的數(shù)據(jù)和函數(shù)等的程序代碼可重復(fù)使用,這樣可以提高程序的可靠性。5.1派生和繼承的相關(guān)概念和作用10當(dāng)從已有的類(lèi)中派生出新的類(lèi)時(shí),可以對(duì)派生類(lèi)做以下幾種變化:1、

可以繼承基類(lèi)的成員數(shù)據(jù)或成員函數(shù)。2、可以增加新的成員變量。3、可以增加新的成員函數(shù)。4、可以重新定義已有的成員函數(shù)。5、可以改變現(xiàn)有的成員屬性。5.1派生和繼承的相關(guān)概念和作用11類(lèi)A派生類(lèi)B:類(lèi)A為基類(lèi),類(lèi)B為派生類(lèi)。AB但派生并不是簡(jiǎn)單的擴(kuò)充,有可能改變派生類(lèi)中的基類(lèi)的成員性質(zhì)。有三種派生方式:公有派生、保護(hù)派生、私有派生。默認(rèn)的是私有派生。classB:publicA{...};classB:protectedA{...};classB:privateA{...};classB:A{...};A為私有派生5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式12從一個(gè)基類(lèi)派生一個(gè)類(lèi)的一般格式為:classClassName:<Access>BaseClassName{private:......; //私有成員說(shuō)明

public:......; //公有成員說(shuō)明

protected:......; //保護(hù)成員說(shuō)明}派生類(lèi)名基類(lèi)名繼承方式public:表示公有基類(lèi)private:表示私有基類(lèi)(默認(rèn))protected:表示保護(hù)基類(lèi)派生類(lèi)中新增加的成員5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式13公有派生classClassName:publicBaseClassName公有派生時(shí),基類(lèi)中所有成員在派生類(lèi)中保持各個(gè)成員的訪問(wèn)權(quán)限。公有派生,派生類(lèi)中保持基類(lèi)的成員特性基類(lèi)成員屬性派生類(lèi)中派生類(lèi)外公有可以引用可以引用保護(hù)可以引用不可引用私有不可引用不可引用5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式14x(私有)y(保護(hù))z(公有)Getx()Gety()ShowA()Ax(私私有)y(保護(hù))z(公有)Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()publicx在類(lèi)B新增成員中不能直接調(diào)用y在類(lèi)B中可以調(diào)用z在整個(gè)文件中可以調(diào)用對(duì)類(lèi)B的對(duì)象初始化即是對(duì)x,y,z,m,n等全部成員的初始化5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式15classA{intx;protected:inty;public:intz;

A(inta,intb,intc){x=a;y=b;z=c;}//基類(lèi)初始化

intGetx(){returnx;} //返回xintGety(){returny;} //返回yvoidShowA(){cout<<"x="<<x<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n';}};classB:publicA{ intm,n;public: B(inta,intb,intc,intd,inte):A(a,b,c){m=d;n=e;}voidShow(){cout<<“m="<<m<<'\t'<<“n="<<n<<'\n';cout<<"x="<<Getx()<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n';}intSum(){return(Getx()+y+z+m+n);}};voidmain(){Bb1(1,2,3,4,5);b1.ShowA(); b1.Show();cout<<"Sum="<<b1.Sum()<<'\n';cout<<"x="<<b1.Getx()<<'\t';cout<<"y="<<b1.Gety()<<'\t'; cout<<"z="<<b1.z<<'\n';}公有派生對(duì)基類(lèi)初始化因?yàn)閤是基類(lèi)私有,所以在派生類(lèi)和類(lèi)外中不能直接引用因?yàn)閥是基類(lèi)保護(hù),所以在派生類(lèi)中可以直接引用。而在類(lèi)外不可直接引用。因?yàn)閦是基類(lèi)公有,所以在派生類(lèi)中和類(lèi)外均可直接引用。5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式僅對(duì)派生類(lèi)中的新增成員進(jìn)行初始化16私有派生classClassName:privateBaseClassName此時(shí),基類(lèi)中公有成員和保護(hù)成員在派生類(lèi)中均變?yōu)樗接?,在派生?lèi)中仍可直接使用這些成員,基類(lèi)中的私有成員,在派生類(lèi)中不可直接使用。基類(lèi)成員屬性派生類(lèi)派生類(lèi)外公有可以引用不可引用保護(hù)可以引用不可引用私有不可引用不可引用基類(lèi):public:(變?yōu)樗接?在派生類(lèi)中使用,類(lèi)外不可使用

protected:(變?yōu)樗接校┰谂缮?lèi)中使用,類(lèi)外不可使用

private:不能在派生類(lèi)中和類(lèi)外使用5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式17x(私有)y(保護(hù))z(公有)Getx()Gety()ShowA()Ax(私私有)y(私有)z(私有)Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()privatex在類(lèi)B新增加的成員中不能直接調(diào)用y在類(lèi)B中可以調(diào)用z在類(lèi)B中可以調(diào)用對(duì)類(lèi)B的對(duì)象初始化即是對(duì)x,y,z,m,n等全部成員的初始化均為私有類(lèi)B外不能引用5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式18classA{intx;protected:inty;public:intz;

A(inta,intb,intc){x=a;y=b;z=c;}//基類(lèi)初始化

intGetx(){returnx;} //返回xintGety(){returny;} //返回yvoidShowA(){cout<<"x="<<x<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n';}};classB:privateA{ intm,n;public: B(inta,intb,intc,intd,inte):A(a,b,c){m=d;n=e;}voidShow(){cout<<“m="<<m<<'\t'<<“n="<<n<<'\n';cout<<"x="<<Getx()<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n';}intSum(){return(Getx()+y+z+m+n);}};voidmain(void){Bb1(1,2,3,4,5);

b1.ShowA(); b1.Show();cout<<"Sum="<<b1.Sum()<<'\n';cout<<"x="<<b1.Getx()<<'\t';cout<<"y="<<b1.Gety()<<'\t'; cout<<"z="<<b1.z<<'\n';}私有派生對(duì)基類(lèi)初始化因?yàn)閤是基類(lèi)私有,所以在派生類(lèi)和類(lèi)外中不能直接引用y是基類(lèi)保護(hù),所以在派生類(lèi)中可以直接引用。而在類(lèi)外不可直接引用。z是基類(lèi)公有,私有派生變?yōu)樗接校栽谂缮?lèi)中可直接引用,而在類(lèi)外不可。這些函數(shù)都是基類(lèi)公有,在類(lèi)外不可使用。Aa1(1,2,3);a1.ShowA();19保護(hù)派生classClassName:protectedBaseClassName此時(shí),基類(lèi)中公有和保護(hù)成員在派生類(lèi)中均變?yōu)楸Wo(hù)的,在派生類(lèi)中仍可直接使用這些成員,基類(lèi)中的私有成員,在派生類(lèi)中不可直接使用?;?lèi)成員屬性派生類(lèi)派生類(lèi)外公有可以引用不可引用保護(hù)可以引用不可引用私有不可引用不可引用基類(lèi):public:(變?yōu)楸Wo(hù))在派生類(lèi)中使用,類(lèi)外不可使用

protected:(仍為保護(hù))在派生類(lèi)中使用,類(lèi)外不可使用

private:不能在派生類(lèi)中和類(lèi)外使用5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式20x(私有)y(保護(hù))z(公有)Getx()Gety()ShowA()Ax(私私有)y(保護(hù))z(保護(hù))Getx()Gety()ShowA()Bm(私有)n(私有)B()Show()Sum()protectedx在類(lèi)B新增加的成員中不能直接調(diào)用y在類(lèi)B中可以調(diào)用z在類(lèi)B中可以調(diào)用對(duì)類(lèi)B的對(duì)象初始化即是對(duì)x,y,z,m,n等全部成員的初始化均為保護(hù)類(lèi)B外不能引用5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式21protected成員是一種具有血緣關(guān)系內(nèi)外有別的成員。它對(duì)派生類(lèi)的對(duì)象而言,是公開(kāi)成員,可以訪問(wèn),對(duì)血緣外部而言,與私有成員一樣被隱蔽。5.2三種繼承的派生類(lèi)的成員訪問(wèn)方式22當(dāng)定義了一個(gè)類(lèi),這個(gè)類(lèi)只能用作基類(lèi)來(lái)派生出新的類(lèi),而不能用這種類(lèi)來(lái)定義對(duì)象時(shí),稱(chēng)這種類(lèi)為抽象類(lèi)。當(dāng)對(duì)某些特殊的對(duì)象要進(jìn)行很好地封裝時(shí),需要定義抽象類(lèi)。將類(lèi)的構(gòu)造函數(shù)或析構(gòu)函數(shù)的訪問(wèn)權(quán)限定義為保護(hù)的時(shí),這種類(lèi)為抽象類(lèi)。5.3抽象類(lèi)與保護(hù)的成員函數(shù)23當(dāng)把類(lèi)中的構(gòu)造函數(shù)或析構(gòu)函數(shù)說(shuō)明為私有的時(shí),所定義的類(lèi)通常是沒(méi)有任何實(shí)用意義的,一般情況下,不能用它來(lái)產(chǎn)生對(duì)象,也不能用它來(lái)產(chǎn)生派生類(lèi)。

5.3抽象類(lèi)與保護(hù)的成員函數(shù)24x(私有)y(私有)A()(保護(hù))ShowA()(公有)Ax(私私有)y(私私有)A()(保護(hù))ShowA()Bm(私有)B()Show()public在類(lèi)B中不能定義A的對(duì)象在任何時(shí)候都不能定義A的對(duì)象但可以在初始化類(lèi)B的對(duì)象時(shí)初始化原類(lèi)A中的成員,因?yàn)锳()在類(lèi)B中是可以被調(diào)用的。5.3抽象類(lèi)與保護(hù)的成員函數(shù)25classA{intx,y;protected:A(inta,intb){x=a;y=b;}//基類(lèi)初始化public:voidShowA(){cout<<"x="<<x<<'\t'<<"y="<<y<<'\n';}};classB:publicA{ intm;Aa1; //在派生類(lèi)中也不可以定義A的對(duì)象,實(shí)際上還是類(lèi)外調(diào)用public:B(inta,intb,intc):A(a,b)//可以在派生類(lèi)中調(diào)用A的構(gòu)造函數(shù)

{m=c;}voidShow(){cout<<“m="<<m<<'\n';ShowA();}};voidmain(){Bb1(1,2,3);//可以定義派生類(lèi)對(duì)象

b1.Show();

Aaa; //不可定義A的對(duì)象}a1(4,5)5.3抽象類(lèi)與保護(hù)的成員函數(shù)26可以用多個(gè)基類(lèi)來(lái)派生一個(gè)類(lèi)。ABCD多重繼承是單一繼承的擴(kuò)展派生類(lèi)中新定義的成員5.4多重繼承27格式為:class類(lèi)名:<Access>類(lèi)名1,...,<Access>類(lèi)名n{private:......;//私有成員說(shuō)明;public:......;//公有成員說(shuō)明;protected:......;//保護(hù)的成員說(shuō)明;};繼承方式classD:publicA,protectedB,privateC{....//派生類(lèi)中新增加成員};5.4多重繼承28classA{ intx1,y1;public: A(inta,intb) {x1=a;y1=b; }voidShowA(void){cout<<"A.x="<<x1<<'\t'<<"A.y="<<y1<<endl;}};classB{intx2,y2;public: B(inta,intb) {x2=a;y2=b; }voidShowB(){cout<<"B.x="<<x2<<'\t'<<"B.y="<<y2<<endl;}};classC:publicA,privateB{ intx,y;public: C(inta,intb,intc,intd,inte,intf):A(a,b),B(c,d) {x=e;y=f;}voidShowC(){cout<<"C.x="<<x<<'\t'<<"C.y="<<y<<endl;

ShowA();ShowB(); }};voidmain(){ Cc(1,2,3,4,5,6); c.ShowC();

c.ShowA();

c.ShowB();}公有派生私有派生仍為公有成為私有非法,私有類(lèi)外不可調(diào)用Bb1(10,20);b1.ShowB();29由于構(gòu)造函數(shù)不能被繼承,故派生類(lèi)的構(gòu)造函數(shù)必須調(diào)用基類(lèi)的構(gòu)造函數(shù)來(lái)初始化基類(lèi)成員和基類(lèi)子對(duì)象。若派生類(lèi)中含有子對(duì)象,則派生類(lèi)構(gòu)造函數(shù)的調(diào)用順序如下:基類(lèi)的構(gòu)造函數(shù)子對(duì)象類(lèi)的構(gòu)造函數(shù)派生類(lèi)的構(gòu)造函數(shù)5.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)30classB:publicA{inty;

Aa1;public:B(inta,intb):A(a),a1(3){y=b;}.......};當(dāng)撤銷(xiāo)派生類(lèi)對(duì)象時(shí),析構(gòu)函數(shù)的調(diào)用正好相反?;?lèi)的構(gòu)造函數(shù)子對(duì)象類(lèi)的構(gòu)造函數(shù)派生類(lèi)的構(gòu)造函數(shù)5.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)基類(lèi)成員構(gòu)造用基類(lèi)名,基類(lèi)子對(duì)象構(gòu)造用對(duì)象名基類(lèi)成員構(gòu)造基類(lèi)子對(duì)象構(gòu)造31classBase1{ intx;public:Base1(inta){ x=a;cout<<"調(diào)用基類(lèi)1的構(gòu)造函數(shù)!\n"; } ~Base1(){ cout<<"調(diào)用基類(lèi)1的析構(gòu)函數(shù)!\n"; }};classBase2{ inty;public:Base2(inta){ y=a;cout<<"調(diào)用基類(lèi)2的構(gòu)造函數(shù)!\n"; } ~Base2(){ cout<<"調(diào)用基類(lèi)2的析構(gòu)函數(shù)!\n"; }};classDerived:publicBase2,publicBase1{ intz;public:Derived(inta,intb):Base1(a),Base2(20){z=b;cout<<"調(diào)用派生類(lèi)的構(gòu)造函數(shù)!\n";}~Derived(){cout<<"調(diào)用派生類(lèi)的析構(gòu)函數(shù)!\n";}};voidmain(){ Derivedc(100,200);}調(diào)用基類(lèi)2的構(gòu)造函數(shù)調(diào)用基類(lèi)1的構(gòu)造函數(shù)調(diào)用派生類(lèi)的構(gòu)造函數(shù)調(diào)用派生類(lèi)的析構(gòu)函數(shù)調(diào)用基類(lèi)1的析構(gòu)函數(shù)調(diào)用基類(lèi)2的析構(gòu)函數(shù)先說(shuō)明基類(lèi)25.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)32classDerived:publicBase2,publicBase1{ intz; Base1b1,b2;public:Derived(inta,intb):Base1(a),Base2(20),b1(200),b2(a+b){z=b;cout<<"調(diào)用派生類(lèi)的構(gòu)造函數(shù)!\n";}~Derived(){cout<<"調(diào)用派生類(lèi)的析構(gòu)函數(shù)!\n";}};voidmain(){ Derivedc(100,200);}基類(lèi)子對(duì)象基類(lèi)成員構(gòu)造基類(lèi)子對(duì)象構(gòu)造基類(lèi)成員構(gòu)造用基類(lèi)名,基類(lèi)子對(duì)象構(gòu)造用對(duì)象名5.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)33classBase1{ intx;public:Base1(inta){ x=a;cout<<"調(diào)用基類(lèi)1的構(gòu)造函數(shù)!\n"; } ~Base1(){ cout<<"調(diào)用基類(lèi)1的析構(gòu)函數(shù)!\n"; }};classBase2{ inty;public:Base2(inta){ y=a;cout<<"調(diào)用基類(lèi)2的構(gòu)造函數(shù)!\n"; } ~Base2(){ cout<<"調(diào)用基類(lèi)2的析構(gòu)函數(shù)!\n"; }};classDerived:publicBase2,publicBase1{ intz; Base1b1,b2;public:Derived(inta,intb):Base1(a),Base2(20),b1(200),b2(a+b){z=b;cout<<"調(diào)用派生類(lèi)的構(gòu)造函數(shù)!\n";}~Derived(){cout<<"調(diào)用派生類(lèi)的析構(gòu)函數(shù)!\n";}};voidmain(){ Derivedc(100,200);}5.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)34調(diào)用基類(lèi)2的構(gòu)造函數(shù)調(diào)用基類(lèi)1的構(gòu)造函數(shù)調(diào)用派生類(lèi)的構(gòu)造函數(shù)調(diào)用派生類(lèi)的析構(gòu)函數(shù)調(diào)用基類(lèi)1的析構(gòu)函數(shù)調(diào)用基類(lèi)2的析構(gòu)函數(shù)調(diào)用基類(lèi)1的構(gòu)造函數(shù)調(diào)用基類(lèi)1的構(gòu)造函數(shù)調(diào)用基類(lèi)1的析構(gòu)函數(shù)調(diào)用基類(lèi)1的析構(gòu)函數(shù)說(shuō)明基類(lèi)1的對(duì)象b1,b25.5有子對(duì)象的派生類(lèi)的構(gòu)造函數(shù)35沖突ABCx…x…x…D…x…x…xD()dDv;v.x=5;public派生類(lèi)對(duì)象產(chǎn)生了沖突v.A::x=5;用類(lèi)作用符限定5.6多重繼承引起的二義性36classA{public:intx;

voidShow(){cout<<"x="<<x<<'\n';}A(inta=0){x=a;} };classB{public:intx;voidShow(){cout<<"x="<<x<<'\n';}B(inta=0){x=a;}};classC:publicA,publicB{ inty;public:voidSetx(inta){x=a;}

//c1對(duì)象中有兩個(gè)x成員

voidSety(intb){y=b;} intGety(){returny;}};voidmain(){ Cc1; c1.Show();//c1對(duì)象中有兩個(gè)Show()函數(shù)

}這時(shí),可以利用類(lèi)作用域符::來(lái)指明數(shù)據(jù)或函數(shù)的來(lái)源。如:A::x=a;

c1.B::Show();5.6多重繼承引起的二義性37支配規(guī)則Ax…Dpublicx…xD()基類(lèi)成員派生類(lèi)新增成員Dv;v.x=5;當(dāng)派生類(lèi)中新增加的數(shù)據(jù)或函數(shù)與基類(lèi)中原有的同名時(shí),若不加限制,則優(yōu)先調(diào)用派生類(lèi)中的成員,即后面的覆蓋前面的。55.6多重繼承引起的二義性38classA{public: intx;

voidShow(){cout<<"x="<<x<<'\n';}};classB{public: inty;

voidShow(){cout<<"y="<<y<<'\n';}};classC:publicA,publicB{public: inty;//類(lèi)B和類(lèi)C均有y的成員};voidmain(){Cc1; c1.x=100;c1.y=200; //給派生類(lèi)中的y賦值

c1.B::y=300; //給基類(lèi)B中的y賦值

c1.A::Show(); c1.B::Show(); //用作用域運(yùn)算符限定調(diào)用的函數(shù)

cout<<"y="<<c1.y<<'\n'; //輸出派生類(lèi)中的y值

cout<<"y="<<c1.B::y<<'\n'; //輸出基類(lèi)B中的y值}當(dāng)派生類(lèi)中新增加的數(shù)據(jù)或函數(shù)與基類(lèi)中原有的同名時(shí),若不加限制,則優(yōu)先調(diào)用派生類(lèi)中的成員,即后面的覆蓋前面的。5.6多重繼承引起的二義性39classA{public: intx; A(inta=0){x=a;}};classB{public: inty; B(inta=0){y=a;}};classC:publicA{ intz; Bb1; Aa1;public: C(inta,intb,intm):A(a),b1(b),a1(a+b){z=m;} voidShow(){ cout<<"x="<<x<<'\t'; cout<<"y="<<b1.y<<'\t'; cout<<"x="<<z<<'\n'; cout<<"a1.x="<<a1.x<<endl; }};voidmain(){ Cc1(100,200,500); c1.Show();}xzShow()a1.xb1.yC的對(duì)象所占空間從基類(lèi)A中繼承在類(lèi)C中新說(shuō)明在類(lèi)C中新說(shuō)明在類(lèi)C中新說(shuō)明在類(lèi)C中新說(shuō)明從基類(lèi)A中繼承新說(shuō)明類(lèi)A對(duì)象中的x5.6多重繼承引起的二義性40基類(lèi)與對(duì)象成員任一基類(lèi)在派生類(lèi)中只能繼承一次,否則,會(huì)造成成員名的沖突

若在派生類(lèi)中,確實(shí)要有二個(gè)以上基類(lèi)的成員,則可用基類(lèi)的二個(gè)對(duì)象作為派生類(lèi)的成員。把一個(gè)類(lèi)作為派生類(lèi)的基類(lèi)或把一個(gè)類(lèi)的對(duì)象作為一個(gè)類(lèi)的成員,在使用上是有區(qū)別的:在派生類(lèi)中可直接使用基類(lèi)的成員(訪問(wèn)權(quán)限允許的話),但要使用對(duì)象成員的成員時(shí),必須在對(duì)象名后加上成員運(yùn)算符“.”和成員名。5.6多重繼承引起的二義性41例題:在平面上作兩個(gè)點(diǎn),連一直線,求直線的長(zhǎng)度和直線中點(diǎn)的坐標(biāo)。要求如下:基類(lèi)為Dot,有兩個(gè)公有數(shù)據(jù)成員,即平面上的坐標(biāo)(x,y),同時(shí)有構(gòu)造函數(shù)及打印函數(shù)。派生類(lèi)為L(zhǎng)ine,有兩個(gè)基類(lèi)Dot對(duì)象,分別存放兩點(diǎn)的坐標(biāo),同時(shí),從基類(lèi)繼承了一個(gè)Dot數(shù)據(jù),存放直線中點(diǎn)的坐標(biāo)。5.7應(yīng)用舉例xyDot(x,y)(構(gòu)造)Dot(&dot)(拷貝)Show()Dot的對(duì)象空間x(中點(diǎn))y(中點(diǎn))Show()d1xyShow()d2xyShow()Line(dot1,dot2)Showl()Line對(duì)象空間從基類(lèi)繼承基類(lèi)對(duì)象425.7應(yīng)用舉例43classDot{public: floatx,y; Dot(floata=0,floatb=0){x=a;y=b;} voidShow(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};classLine:publicDot{

Dotd1,d2;public: Line(Dotdot1,Dotdot2):d1(dot1),d2(dot2) {x=(d1.x+d2.x)/2;y=(d1.x+d2.y)/2;}voidShowl(){cout<<"Dot1:";d1.Show();cout<<"Dot2:";d2.Show();cout<<"Length="<<sqrt((d1.x-d2.x)*(d1.x-d2.x)+(d1.y-d2.y)*(d1.y-d2.y));cout<<endl;cout<<"Center:"<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(){floata,b;cout<<"InputDot1:\n";cin>>a>>b;

Dotdot1(a,b);//調(diào)用Dot的構(gòu)造函數(shù)

cout<<"InputDot2:\n";cin>>a>>b;

Dotdot2(a,b);

Lineline(dot1,dot2);line.Showl();}用坐標(biāo)初始化Dot對(duì)象在Line中新說(shuō)明的成員對(duì)成員初始化x,y是繼承基類(lèi)的成員打印坐標(biāo)5.7應(yīng)用舉例44基類(lèi)對(duì)象派生類(lèi)對(duì)象賦值兼容規(guī)則,即相互之間能否賦值?

可以將派生類(lèi)對(duì)象的值賦給基類(lèi)對(duì)象。反之不行Baseb;Derived;b=d;

只是將從基類(lèi)繼承來(lái)的成員賦值。5.8基類(lèi)與派生類(lèi)的轉(zhuǎn)換45Dotdot;Lineline;Dot=line;Line=dot;非法xyDot(x,y)(構(gòu)造)Dot(&dot)(拷貝)Show()x(中點(diǎn))y(中點(diǎn))Show()d1xyShow()d2xyShow()Line(dot1,dot2)Showl()Line對(duì)象空間從基類(lèi)繼承基類(lèi)對(duì)象Dot的對(duì)象空間5.8基類(lèi)與派生類(lèi)的轉(zhuǎn)換46可以將一個(gè)派生類(lèi)對(duì)象的地址賦給基類(lèi)的指針變量。基類(lèi)對(duì)象派生類(lèi)對(duì)象Baseb;Derived;Base*basep;basepbasep=&b;basepbasep=&dbasep只能引用從基類(lèi)繼承來(lái)的成員。基類(lèi)指針派生類(lèi)對(duì)象基類(lèi)對(duì)象5.8基類(lèi)與派生類(lèi)的轉(zhuǎn)換47派生類(lèi)對(duì)象可以初始化基類(lèi)的引用。Derived;Base&basei=d;基類(lèi)對(duì)象派生類(lèi)對(duì)象Baseb;Derived;別名baseibasei只能引用從基類(lèi)繼承來(lái)的成員?;?lèi)引用派生類(lèi)對(duì)象5.8基類(lèi)與派生類(lèi)的轉(zhuǎn)換48classA{public: intx; A(inta=0){x=a;}};classB{public: inty; B(inta=0){y=a;}};classC:publicA,publicB{intz;public: C(inta,intb,intm):A(a),B(b) {z=m;} voidShow(){ cout<<"x="<<x<<'\t'; cout<<"y="<<y<<‘\t’; cout<<"z="<<z<<'\n'; }};voidmain(void){ Aa1(100);

Bb1(200); Cc1(10,20,50); cout<<"a1.x="<<a1.x<<endl; cout<<"b1.y="<<b1.y<<endl; c1.Show(); a1=c1; b1=c1;//派生類(lèi)對(duì)象向基類(lèi)對(duì)象賦值

cout<<"a1.x="<<a1.x<<endl; cout<<"b1.y="<<b1.y<<endl;

A*p;

p=&c1; //基類(lèi)指針指向派生類(lèi)對(duì)象 p->Show();}xyzC()Show()102050a1.x=100b1.y=200x=10 y=20 z=50a1.x=10b1.y=20c1xA()a1yB()b11002001020錯(cuò)誤!49類(lèi)B是類(lèi)A的派生類(lèi)xA()xA()yB()xA()zC()A類(lèi)B類(lèi)C類(lèi)dxD()xA()zC()yB()A()xD類(lèi)類(lèi)A拷貝類(lèi)C是類(lèi)A的派生類(lèi)類(lèi)D是類(lèi)B和類(lèi)C的派生類(lèi)這樣,類(lèi)D中就有兩份類(lèi)A的拷貝B類(lèi)C類(lèi)類(lèi)A拷貝5.9虛基類(lèi)50這種同一個(gè)公共的基類(lèi)在派生類(lèi)中產(chǎn)生多個(gè)拷貝,不僅多占用了存儲(chǔ)空間,而且可能會(huì)造成多個(gè)拷貝中的數(shù)據(jù)不一致

和模糊的引用。Dd;d.x=10;//模糊引用dxD()xA()zC()yB()A()xD類(lèi)類(lèi)A拷貝B類(lèi)C類(lèi)類(lèi)A拷貝5.9虛基類(lèi)51cla

溫馨提示

  • 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)論