版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
面向對象程序設計繼承演示文稿第一頁,共八十六頁。面向對象程序設計繼承第二頁,共八十六頁。第4章繼承繼承使軟件復用變得簡單、易行,可以通過繼承復用已有的程序資源,縮短軟件開發(fā)的周期。本章主要介紹繼承的方式,要注意在繼承方式下派生類與基類對象之間的關系,以及派生類構造函數(shù)如何提供對基類的構造。第三頁,共八十六頁。4.1繼承的概念1、繼承的概念第四頁,共八十六頁。以存在的類為基礎定義新的類,新類即捅有基類的數(shù)據成員和成員函數(shù)。Personchar*name;char*id_card_no;boolgender;Studentcharstudent_no;Dateenroll_date;……FacultyDatehire_date;Degreedegree;……AdministratorDatehire_date;Rankrank;……4.1繼承的概念第五頁,共八十六頁。2、繼承目的代碼重用coderesue描述能力:類屬關系廣泛存在IsAvs.HasA3、有關概念
基類,超類
派生類,子類4.1繼承的概念第六頁,共八十六頁。4、派生類可實施的對基類的改變增加新的數(shù)據成員和成員函數(shù)。重載基類的成員函數(shù)。重定義基類已有的成員函數(shù)。改變基類成員在派生類中的訪問屬性。5、派生類不能繼承基類的以下內容基類的構造函數(shù)和析構函數(shù)?;惖挠言瘮?shù)。靜態(tài)數(shù)據成員和靜態(tài)成員函數(shù)4.1繼承的概念第七頁,共八十六頁。4.2protected和繼承1、關于protected權限protected可以用來設置類成員的訪問權限,具有protected訪問權限的成員稱為保護成員。protected主要用于繼承,對于一個不被任何派生類繼承的類而言,protected訪問屬性與private完全相同。在繼承結構中,基類的protected成員雖然不能被派生類的外部函數(shù)訪問,但卻能夠被其派生類直接訪問。第八頁,共八十六頁。4.2protected和繼承【例4-1】保護成員的例子//Eg4-1.cpp#include<iostream>usingnamespacestd;classB{private:inti;protected:intj;public:intk;};第九頁,共八十六頁。classD:publicB{//L1,此表示D從B派生public:voidf(){i=1; //L1,錯誤
j=2; //L2,正確k=3; //L3,正確}};voidmain(){Bb;b.i=1; //L4,錯誤b.j=2; //L5,錯誤b.k=3;}第十頁,共八十六頁。4.2protected和繼承2、例4.1類繼承后的成員訪問權限第十一頁,共八十六頁。4.2protected和繼承3、說明①一個類如果不被其他類繼承,則其protected和private成員具有相同的訪問屬性。只能被本類成員函數(shù)訪問,不能被類的外部函數(shù)訪問。②一個類如果被其他類繼承,派生類不能直接訪問它的private成員,但能夠直接訪問它的protected成員,這就是protected成員與private成員的區(qū)別。③盡管基類的public和protected成員都能被派生類直接訪問,但它們是有區(qū)別的。public成員能夠被類的外部函數(shù)直接訪問,而protected成員則不能。第十二頁,共八十六頁。4.3
繼承方式1、C++的繼承類型可分為公有繼承、保護繼承和私有繼承,也稱為公有派生、保護派生和私有派生。不同繼承方式會不同程度地影響基類成員在派生類中的訪問權限。
第十三頁,共八十六頁。4.3
繼承方式2、繼承語法形式classB{……};classD:[private|protected|public]B{
……};第十四頁,共八十六頁。3、public繼承最常見的派生方式維持基類成員的可訪問性派生類不可直接訪問基類的private成員,可通過基類的共有成員函數(shù)訪問4.3
繼承方式第十五頁,共八十六頁。例題ch4_2.cppclassbase{ intx;public: voidsetx(intn){ x=n; } intgetx(){ returnx;} voidshowx() { cout<<x<<endl;}};classderived:publicbase{ inty;public: voidsety(intn){ y=n; } voidsety(){ y=getx();} voidshowy() { cout<<y<<endl;}};Setx()Getx()Showx()xSetx()Getx()Showx()xSety()Gety()Showy()y接口私有數(shù)據basederived第十六頁,共八十六頁。voidmain(){ derivedobj; obj.setx(10); obj.sety(20); obj.showx(); obj.showy(); obj.sety(); obj.showx(); obj.showy();}3.public繼承第十七頁,共八十六頁。4.私有繼承Private基類的中的public成員在派生類中是private,private成員在派生類中不可訪問?!纠?】私有繼承的例子//Eg.cpp#include<iostream>usingnamespacestd;classBase{intx;public:voidsetx(intn){x=n;}intgetx(){returnx;}voidshowx(){cout<<x<<endl;}};第十八頁,共八十六頁。classderived:privatebase{ inty;public: voidsety(intn){y=n; } voidsety(){ y=getx();} voidshowy() { cout<<y<<endl;}};voidmain(){ derivedobj; obj.setx(10);//cannotaccess obj.sety(20); obj.showx();//cannotaccess obj.showy(); }Setx()Getx()Showx()xSetx()Getx()Showx()xSety()Gety()Showy()y接口私有數(shù)據basederived第十九頁,共八十六頁。4.2protected和繼承派生方式為protected的繼承稱為保護繼承,在這種繼承方式下,基類的public成員在派生類中會變成protected成員,基類的protected和private成員在派生類中保持原來的訪問權限。
【例4】保護繼承的例子。#include<iostream>usingnamespacestd;classBase{intx;protected:intgetx(){returnx;}public:voidsetx(intn){x=n;}voidshowx(){cout<<x<<endl;}};第二十頁,共八十六頁。classDerived:protectedBase{inty;public:voidsety(intn){y=n;}voidsety(){y=getx();}//訪問基類的保護成員
voidshowy(){cout<<y<<endl;}};voidmain(){Derivedobj;obj.setx(10);//錯誤
obj.sety(20);obj.showx(); //錯誤,
obj.showy();}第二十一頁,共八十六頁。表4-1:基類成員在派生類中的訪問權限不能繼承的基類內容1.構造函數(shù)、析構函數(shù)2.友員關系3.針對基類定義的一些特殊運算符,如new等。派生類基類public繼承protected繼承private繼承publicprotectedprivatepublicprotectedprivatepublicprotectedprivatepublic√
√
√protected
√
√
√private
√
√
√第二十二頁,共八十六頁。4.4基類與派生類的關系、成員函數(shù)的重定義和名字隱藏派生類對基類成員函數(shù)的重定義或重載會影響基類成員函數(shù)在派生類中的可見性,基類的同名成員函數(shù)會被派生類重載的同名函數(shù)所隱藏?!纠?-3】派生類重載基類成員函數(shù)的例子。第二十三頁,共八十六頁。//Eg4-3.cpp#include<iostream>usingnamespacestd;classBase{intx;public:voidsetx(inti){x=i;}voidset(intn){x=n;}voidprint(){cout<<"Baseclass:x="<<x<<endl;}};第二十四頁,共八十六頁。classDerived:publicBase{intm,n;public:voidset(intp,intk){m=p;n=k;} //L1重載基類的成員函數(shù)set()voidset(inti,intj,intk){ //L2重載成員函數(shù)set()Base::set(i); //L3調用基類成員函數(shù)set()m=j;n=k;}voidprint(){ //L4重定義基類的成員函數(shù)print()Base::print();cout<<"DerivedClass:m="<<m<<endl;cout<<"DerivedClass:n="<<n<<endl;}};第二十五頁,共八十六頁。voidmain(){Derivedd; //L5d.set(1,3); //L6d.print(); //L7d.set(5,6,7); //L8d.print(); //L9//d.set(10); //L10,錯誤,只能是d.Base::set(10)d.Base::print(); //L11d.setx(8); //L12}第二十六頁,共八十六頁。2、派生類和基類的關系派生類繼承了基類的所有成員,盡管有些繼承的成員是不可訪問的派生類可以:添加新的數(shù)據成員和/或函數(shù)成員修改繼承的函數(shù)成員的行為(overloading)覆蓋繼承的函數(shù)成員(overriding)classBase {basemembers;};classDerived:Base {newmembers;};basemembersnewmembersthis指針Derivedmembers第二十七頁,共八十六頁。派生類對基類成員的訪問形式通過派生類對象直接訪問基類成員在派生類成員函數(shù)中直接訪問基類成員通過基類名字限定訪問被重載的基類成員名4.4.2基類成員訪問第二十八頁,共八十六頁。4.4基類與派生類的關系【例】在派生類中訪問基類成員。//Eg.cpp#include<iostream>usingnamespacestd;classB{intx;public:voidset(inti){x=i;}voidsetx(inti){x=i;}voidprintx(){cout<<"x="<<x<<endl;}};第二十九頁,共八十六頁。classD:publicB{inty;public:voidsety(intp){y=p;}voidprinty(){cout<<"y="<<y<<endl;}voidsetxy(inti,intj){setx(i); //L1在派生類成員函數(shù)中直接訪問基類成員
y=j;}voidset(inti,intj){B::set(i); //L2訪問基類set成員
y=j;}};voidmain(){Dobj;obj.setx(2); //L3訪問基類成員
obj.printx(); //L4訪問基類成員,輸出x=2obj.sety(3); //L5訪問派生類成員
obj.set(1,2); //L6訪問派生類set成員
obj.B::set(3); //L7訪問基類set成員}第三十頁,共八十六頁。4.5構造函數(shù)和析構函數(shù)類對象成員的構造先構造成員再構造自身(調用構造函數(shù))例題ch.cpp第三十一頁,共八十六頁。classA{public: A(){cout<<"ConstructingA"<<endl;} ~A(){cout<<"DestructingA"<<endl;}};classB{public: B(){cout<<"ConstructingB"<<endl;} ~B(){cout<<"DestructingB"<<endl;}};第三十二頁,共八十六頁。classC{public: C(){cout<<"ConstructingC"<<endl;} ~C(){cout<<"DestructingC"<<endl;} Bb; Aa;};voidmain(){ Cc;}ConstructingBConstructingAConstructingCDestructingCDestructingADestructingB如果:classB:publicA{}classC:publicB{}結果又當如何?第三十三頁,共八十六頁。4.5.1派生類構造函數(shù)、析構函數(shù)的定義和調用次序派生類可能有多個基類,也可能包括多個成員對象,在創(chuàng)建派生類對象時,派生類的構造函數(shù)除了要負責本類成員的初始化外,還要調用基類和成員對象的構造函數(shù),并向它們傳遞參數(shù),以完成基類子對象和成員對象的建立和初始化。派生類只能采用構造函數(shù)初始化列表的方式向基類或成員對象的構造函數(shù)傳遞參數(shù),形式如下:派生類構造函數(shù)名(參數(shù)表):基類構造函數(shù)名(參數(shù)表),成員對象名1(參數(shù)表),…{//……}第三十四頁,共八十六頁。4.5.1派生類構造函數(shù)、析構函數(shù)的定義和調用次序【例4-4】派生類Derived以構造函數(shù)初始化列表的方式向基類構造函數(shù)提供參數(shù)。//Eg4-4.cpp#include<iostream>usingnamespacestd;classBase{ intx;public:
Base(inta){ //L1 x=a; cout<<"ConstructingBase:x="<<x<<endl; }~Base(){cout<<"DestructingBase:x="<<x<<endl;}};第三十五頁,共八十六頁。classDerived:publicBase{ intz;public:Derived(inti,intj,intk):Base(i),b(j){ //L2 z=k; cout<<"ConstructingDerived:z="<<z<<endl; }~Derived(){cout<<"DestructingDerived:z="<<z<<endl;}
Baseb; //L4};voidmain(){Derivedd(1,2,3); //L6}第三十六頁,共八十六頁。派生類對象的構造先構造基類再構造成員最后構造自身(調用構造函數(shù))基類構造順序由派生層次決定:最遠的基類最先構造成員構造順序和定義順序符合析構函數(shù)的析構順序與構造相反4.5.1派生類構造函數(shù)、析構函數(shù)的定義和調用次序第三十七頁,共八十六頁。例題ch.cppclassA{public: A(){cout<<"ConstructingA"<<endl;} ~A(){cout<<"DestructingA"<<endl;}};classB{public: B(){cout<<"ConstructingB"<<endl;} ~B(){cout<<"DestructingB"<<endl;}};第三十八頁,共八十六頁。classC{public: C(){cout<<"ConstructingC"<<endl;} ~C(){cout<<"DestructingC"<<endl;}};第三十九頁,共八十六頁。classD:publicC{public: D(){cout<<"ConstructingD"<<endl;} ~D(){cout<<"DestructingD"<<endl;} Bb; Aa; Cc;};voidmain(){ Dd;}ConstructingCConstructingBConstructingAConstructingCConstructingDDestructingDDestructingCDestructingADestructingBDestructingC第四十頁,共八十六頁。4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則1、派生類可以不定義構造函數(shù)的情況當具有下述情況之一時,派生類可以不定義構造函數(shù)?;悰]有定義任何構造函數(shù)。基類具有缺省參數(shù)的構造函數(shù)。基類具有無參構造函數(shù)。第四十一頁,共八十六頁?!纠?-5】沒有構造函數(shù)的派生類。//Eg4-5.cpp#include<iostream>usingnamespacestd;classA{public:A(){cout<<"ConstructingA"<<endl;}~A(){cout<<"DestructingA"<<endl;}};classB:publicA{public:~B(){cout<<"DestructingB"<<endl;}};voidmain(){Bb;}第四十二頁,共八十六頁。4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則2、派生類必須定義構造函數(shù)的情況
當基類或成員對象所屬類只含有帶參數(shù)的構造函數(shù)時,即使派生類本身沒有數(shù)據成員要初始化,它也必須定義構造函數(shù),并以構造函數(shù)初始化列表的方式向基類和成員對象的構造函數(shù)傳遞參數(shù),以實現(xiàn)基類子對象和成員對象的初始化。第四十三頁,共八十六頁。4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則【例4-6】派生類構造函數(shù)的定義。//Eg4-6.cpp#include<iostream>usingnamespacestd;classPoint{protected:intx,y;public:Point(inta,intb=0){x=a;y=b;cout<<"constructingpoint("<<x<<","<<y<<")"<<endl;}};第四十四頁,共八十六頁。classLine:publicPoint{protected:intlen;public:Line(inta,intb,intl):Point(a,b){ //構造函數(shù)初始化列表
len=l;cout<<"ConstructingLine,len..."<<len<<endl;}};voidmain(){LineL1(1,2,3);}第四十五頁,共八十六頁。3、派生類的構造函數(shù)只負責直接基類的初始化C++語言標準有一條規(guī)則:如果派生類的基類同時也是另外一個類的派生類,則每個派生類只負責它的直接基類的構造函數(shù)調用。這條規(guī)則表明當派生類的直接基類只有帶參數(shù)的構造函數(shù),但沒有默認構造函數(shù)時(包括缺省參數(shù)和無參構造函數(shù)),它必須在構造函數(shù)的初始化列表中調用其直接基類的構造函數(shù),并向基類的構造函數(shù)傳遞參數(shù),以實現(xiàn)派生類對象中的基類子對象的初始化。這條規(guī)則有一個例外情況,當派生類存在虛基類時,所有虛基類都由最后的派生類負責初始化。4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則第四十六頁,共八十六頁?!纠?-7】當同時存在直接基類和間接基類時,每個派生類只負責其直接基類的構造。//Eg4-7.cpp#include<iostream>usingnamespacestd;classA{intx;public:A(intaa){x=aa;cout<<"ConstructingA"<<endl;}~A(){cout<<"DestructingA"<<endl;}};第四十七頁,共八十六頁。classB:publicA{public:B(intx):A(x){cout<<"ConstructingB"<<endl;}};classC:publicB{public:C(inty):B(y){cout<<"ConstructingC"<<endl;}};voidmain(){Cc(1);}第四十八頁,共八十六頁。4、構造函數(shù)的調用時間和次序當派生類具有多個基類和多個對象成員,它們的構造函數(shù)將在創(chuàng)建派生類對象時被調用,調用次序如下:基類構造函數(shù)→對象成員構造函數(shù)→派生類構造函數(shù)4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則第四十九頁,共八十六頁。(1)當有多個基類時,將按照它們在繼承方式中的聲明次序調用,與它們在構造函數(shù)初始化列表中的次序無關。當基類A本身又是另一個類B的派生類時,則先調用基類B的構造函數(shù),再調用基類A的構造函數(shù)。(2)當有多個對象成員時,將按它們在派生類中的聲明次序調用,與它們在構造函數(shù)初始化列表中的次序無關。(3)當構造函數(shù)初始化列表中的基類和對象成員的構造函數(shù)調用完成之后,才執(zhí)行派生類構造函數(shù)體中的程序代碼。4.5.2構造函數(shù)和析構函數(shù)的構造規(guī)則第五十頁,共八十六頁。【例4-8】構造函數(shù)的調用次序驗證。//Eg4-8.cpp#include<iostream>usingnamespacestd;classA{intx;public:A(inti=0){x=i;cout<<"A-----"<<x<<endl;}};classB{inty;public:B(inti){y=i;cout<<"B-----"<<y<<endl;}};第五十一頁,共八十六頁。classC{intz;public:C(inti){z=i;cout<<"C-----"<<z<<endl;}};classD:publicB{public:Cc1,c2;Aa0,a4;D():a4(4),c2(2),c1(1),B(1){cout<<"D-----5"<<endl;}};voidmain(){Dd;}第五十二頁,共八十六頁。4.6多重繼承4.6.1多繼承的概念和應用C++允許一個類從一個或多個基類派生。如果一個類只有一個基類,就稱為單一繼承。如果一個類具有兩個或兩個以上的基類,就稱為多重繼承。多繼承的形式如下:class派生類名:[繼承方式]基類名1,[繼承方式]基類名2,
…{……};其中,繼承方式可以是public、protected、private第五十三頁,共八十六頁。4.6.1多繼承的概念和應用第五十四頁,共八十六頁。【例4-9】上圖的簡單程序。//Eg4-9.cpp#include<iostream>usingnamespacestd;classBase1{private:intx;protected:intgetx(){returnx;}public:voidsetx(inta=1){x=a;}};4.6.1多繼承的概念和應用第五十五頁,共八十六頁。classBase2{private:inty;public:voidsety(inta){y=a;}intgety(){returny;}};classBase3{private:intz;public:voidsetz(inta){z=a;}intgetz(){returnz;}};第五十六頁,共八十六頁。classDerived:publicBase1,publicBase2,publicBase3{private:intd;public:voidsetd(inta){d=a;}voiddisplay();};voidDerived::display(){cout<<"Base1....x="<<getx()<<endl;cout<<"Base2....y="<<gety()<<endl;cout<<"Base3....z="<<getz()<<endl;cout<<"Derived..d="<<d<<endl;}voidmain(){Derivedobj;obj.setx(1);obj.sety(2);obj.setz(3);obj.setd(4);obj.display();}第五十七頁,共八十六頁。4.6.2多繼承下的二義性在多繼承方式下,派生類繼承了多個基類的成員,當兩個不同基類擁有同名成員時,容易產生名字沖突問題?!纠?-10】類A和類B是MI的基類,它們都有一個成員函數(shù)f,在類MI中就有通過繼承而來的兩個同名成員函數(shù)f。第五十八頁,共八十六頁。//Eg4-10.cpp#include<iostream>usingnamespacestd;classA{public:voidf(){cout<<"FromA"<<endl;}};classB{public:voidf(){cout<<"FromB"<<endl;}};classMI:publicA,publicB{public:voidg(){cout<<"FromMI"<<endl;}};voidmain(){MImi;mi.f(); //錯誤
mi.A::f(); //正確}第五十九頁,共八十六頁。4.6.3多繼承的構造函數(shù)與析構函數(shù)派生類必須負責為每個基類的構造函數(shù)提供初始化參數(shù),構造的方法和原則與單繼承相同。構造函數(shù)的調用次序仍然是先基類,再對象成員,然后才是派生類的構造函數(shù)?;悩嬙旌瘮?shù)的調用次序與它們在被繼承時的聲明次序相同,與它們在派生類構造函數(shù)的初始化列表中的次序沒有關系。多繼承方式下的析構函數(shù)調用次序仍然與構造函數(shù)的調用次序相反。第六十頁,共八十六頁?!纠?-11】類Base1、Base2、Base3、Derived的繼承關系如圖所示,驗證其構造函數(shù)和析構函數(shù)的調用次序。4.6.3多繼承的構造函數(shù)與析構函數(shù)第六十一頁,共八十六頁。//Eg4-11.cpp#include<iostream>usingnamespacestd;classBase1{private:intx;public:Base1(inta=1){x=a;cout<<"Base1constructorx="<<x<<endl;}~Base1(){cout<<"Base1destructor..."<<endl;}};第六十二頁,共八十六頁。classBase2{private:inty;public:Base2(inta){y=a;cout<<"Base2constructory="<<y<<endl;}~Base2(){cout<<"Base2destructor..."<<endl;}};第六十三頁,共八十六頁。classBase3{private:intz;public:Base3(inta){z=a;cout<<"Base3constructorz="<<z<<endl;}~Base3(){cout<<"Base3destructor..."<<endl;}};第六十四頁,共八十六頁。classDerived:publicBase1,protectedBase2,privateBase3{private:inty;public:Derived(inta,intb,intc):Base3(b),Base2(a){y=c;cout<<"Derivedconstructory="<<y<<endl;}~Derived(){cout<<"Deriveddestructor..."<<endl;}};voidmain(){Derivedd(2,3,4);}第六十五頁,共八十六頁。1.虛擬繼承引入的原因:重復基類派生類間接繼承同一基類使得間接基類(Person)在派生類中有多份拷貝,引發(fā)二義性。DeptHeadFacultyPersonname…AdministratorPersonname
…4.7繼擬繼承第六十六頁,共八十六頁。虛擬基類在派生類中只存在一份拷貝,解決了基類數(shù)據成員的二義性問題4.7繼擬繼承第六十七頁,共八十六頁。2、虛擬繼承virtualinheritance的定義語法classderived_class:virtual[…]base_class虛基類virtualbaseclass被虛擬繼承的基類在其所以的派生類中,僅出現(xiàn)一次4.7繼擬繼承第六十八頁,共八十六頁。classA{public: voidvf(){ cout<<"IcomefromclassA"<<endl; }};classB:publicA{};classC:publicA{};classD:publicB,publicC{};voidmain(){ Dd; d.vf(); //error}ABCDVf()Vf()Vf()B.A::Vf()C.A::Vf()AVf()【例】類A是類B、C的虛基類,類D從類B、C繼承,在類D中調用基類A的成員不會產生二義性。第六十九頁,共八十六頁。classA{public: voidvf(){ cout<<"IcomefromclassA"<<endl; }};classB:virtualpublicA{};classC:virtualpublicA{};classD:publicB,publicC{};voidmain(){ Dd; d.vf(); //okay}ABCDVf()Vf()Vf()A::Vf()將【例】改為虛擬繼承不會產生二義性。第七十頁,共八十六頁。3、虛擬繼承的構造次序虛基類的初始化與一般的多重繼承的初始化在語法上是一樣的,但構造函數(shù)的調用順序不同;若基類由虛基類派生而來,則派生類必須提供對間接基類的構造(即在構造函數(shù)初始列表中構造虛基類,無論此虛基類是直接還是間接基類)調用順序的規(guī)定:先調用虛基類的構造函數(shù),再調用非虛基類的構造函數(shù)若同一層次中包含多個虛基類,這些虛基類的構造函數(shù)按它們的說明的次序調用若虛基類由非基類派生而來,則仍然先調用基類構造函數(shù),再調用派生類構造函數(shù)4.7繼擬繼承第七十一頁,共八十六頁?!纠?-12】虛基類的執(zhí)行次序分析。//Eg4-12.cpp#include<iostream>usingnamespacestd;classA{inta;public:A(){cout<<"ConstructingA"<<endl;}};classB{public:B(){cout<<"ConstructingB"<<endl;}};4.7繼擬繼承第七十二頁,共八十六頁。classB1:virtualpublicB,virtualpublicA{public:B1(inti){cout<<"ConstructingB1"<<endl;}};classB2:publicA,virtualpublicB{public:B2(intj){cout<<"ConstructingB2"<<endl;}};classD:publicB1,publicB2{public:D(intm,intn):B1(m),B2(n){cout<<"ConstructingD"<<endl;}Aa;};
voidmain(){Dd(1,2);}第七十三頁,共八十六頁。4、虛基類由最終派生類初始化在沒有虛擬繼承的情況下,每個派生類的構造函數(shù)只負責其直接基類的初始化。但在虛擬繼承方式下,虛基類則由最終派生類的構造函數(shù)負責初始化。
在虛擬繼承方式下,若最終派生類的構造函數(shù)沒有明確調用虛基類的構造函數(shù),編譯器就會嘗試調用虛基類不需要參數(shù)的構造函數(shù)(包括缺省、無參和缺省參數(shù)的構造函數(shù)),如果沒找到就會產生編譯錯誤。4.7繼擬繼承第七十四頁,共八十六頁?!纠?-13】類A是類B、C的虛基類,類ABC從B、C派生,是繼承結構中的最終派生類,它負責虛基類A的初始化。//Eg4-13.cpp#include<iostream.h>classA{inta;public:A(intx){a=x;cout<<"VirtualBassA..."<<endl;}};第七十五頁,共八十六頁。classB:virtualpublicA{public:B(inti):A(i){cout<<"VirtualBassB..."<<endl;}};classC:virtualpublicA{intx;public:C(inti):A(i){cout<<"ConstructingC..."<<endl;x=i;}};classABC:publicC,publicB{public:ABC(inti,intj,intk):C(i),B(j),A(i)//L1,這里必須對A進行初始化
{cout<<"ConstructingABC..."<<endl;}};voidmain(){ABCobj(1,2,3);}第七十六頁,共八十六頁。4.8基類與派生類對象的關系
基類對象與派生類對象之間存在賦值相容性。包括以下幾種情況:把派生類對象賦值給基類對象。把派生類對象的地址賦值給基類指針。用派生類對象初始化基類對象的引用。反之則不行,即不能把基類對象賦值給派生類對象;不能把基類對象的地址賦值給派生類對象的指針;也不能把基類對象作為派生對象的引用。第七十七頁,共八十六頁?!纠?-14】把派生類對象賦值給基類對象的例子。//Eg4-14cpp#include<iostream>usingna
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)老院消防安全保障制度
- 家庭教育信息反饋制度
- 企業(yè)控煙管理考評獎懲制度
- 公共服務品牌LOGO使用指南及制度
- 結核病防治管理制度
- 檢驗科檢驗質控制度
- 機房管理制度通則
- 冶金行業(yè)特種設備安全檢查與隱患識別制度
- 自來水公司運營效率評估制度
- 2024年汽車貸款合同解除協(xié)議3篇
- 機電工程質量通病與預防措施
- 2024屆北京初三中考 病句修改專題講義及其專題練習 學案
- 充電站光儲一體化項目方案
- 印刷服務投標方案(技術方案)
- python課件第4章 Python的四種典型序列結構
- 《銷售技巧篇》課件
- 美國RAZ分級讀物目錄整理
- 剖析IDC項目質量控制中監(jiān)理應把控的難點與要點
- 汽車車載網絡及總線技術習題匯編(學生版)
- 醫(yī)療器械軟件設計和開發(fā)-全套開發(fā)資料模板范本匯編
- 《針對小班幼兒在建構游戲中擺弄積木行為的實踐支持》 論文
評論
0/150
提交評論