版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
面向?qū)ο缶幊蹋豪^承提綱繼承簡介基類和派生類派生類的定義格式基類和派生類之間的關(guān)系派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù)多繼承多繼承中的二義性問題虛基類繼承簡介繼承(Hierarchy)是C++語言的一種重要機制。繼承是指把已有的類作為基類來定義新的類。新類繼承了其基類的屬性和操作,還可以具有其基類不具備的自己特有的屬性和操作。繼承性為軟件的編寫提供了強有力的機制,提高了軟件的可靠性、易讀性、有效性、可移植性和可重用性。繼承提供了在已有類的根底上開發(fā)出新類的機制,可以節(jié)省重復(fù)代碼的編寫工作,是軟件重用的根底。
BAA派生類是對基類的擴(kuò)充一個類A,對A類加以擴(kuò)展,即增加一些屬性和行為,構(gòu)成一個新類B,此時B類將A類已有的屬性和行為繼承下來。稱類B繼承了A,或稱類A派生了B。A:父類,基類BaseClassB:子類,派生類DerivedClass基類和派生類基類和派生類類的繼承是在現(xiàn)有類的根底之上,創(chuàng)立新類的機制。稱現(xiàn)有的類為基類,新建立的類為派生類。新類繼承了基類的屬性和行為新類是基類的特殊情況。不必從“草稿”開始創(chuàng)立特殊的程序?qū)ο罄^承表達(dá)現(xiàn)實世界的層次概念:交通工具卡車汽車小汽車工具車轎車面包車基類和派生類關(guān)于基類和派生類的關(guān)系,可以表述為:派生類是基類的具體化,而基類那么是派生類的抽象。在C++中,繼承分為單繼承和多繼承:單繼承——派生類只有一個直接基類的繼承方式;多繼承——派生類有多個直接基類的繼承方式。如以下圖所示:外部存儲器軟盤光盤硬盤單繼承ABC單繼承XYZ多繼承基類和派生類直接基類和間接基類父類被稱為子類的直接基類父類的父類或更高層次的父類被稱為這個子類的間接基類
派生類的定義格式〔單繼承〕在C++中,派生類的一般聲明語法如下:class<派生類名>:[繼承方式]<基類名>{
派生類成員聲明;
};其中:
派生類只有一個直接基類為單繼承①class是類聲明的關(guān)鍵字,用于告訴編譯器下面聲明的是一個類。②派生類名是新生成的類名。派生類的定義格式〔單繼承〕派生類的定義格式③共有三種繼承方式:公有繼承〔public〕,私有繼承〔private,系統(tǒng)的默認(rèn)值〕,保護(hù)繼承〔protected〕。派生類的定義格式繼承方式指定派生類成員以及類外對象對繼承來的成員的訪問權(quán)限。不同繼承方式的影響主要表達(dá)在:1、派生類成員對基類成員的訪問控制。2、派生類對象對基類成員的訪問控制。④派生類成員指除了從基類繼承來的所有成員之外,新增加的數(shù)據(jù)和函數(shù)成員。這些新增的成員正是派生類不同于基類的關(guān)鍵所在,是派生類對基類的開展。當(dāng)重用和擴(kuò)充已有的代碼時,就是通過在派生類中新增成員來添加新的屬性和功能??梢哉f,這就是類在繼承根底上的進(jìn)化和開展。派生類的定義格式派生與繼承的實例
公司人員管理系統(tǒng):小型公司人員分為:經(jīng)理、兼職技術(shù)人員、銷售經(jīng)理和兼職推銷員。要求:存儲所有人員的姓名、編號、級別、當(dāng)月薪水,計算月薪總額并顯示全部信息。派生與繼承的實例人員編號在生成人員信息時同時生成,每輸入一個人員信息編號順序加1。程序能夠?qū)Σ煌藛T按不同方法提升級別,月薪的計算方法是:經(jīng)理拿固定月薪;兼職技術(shù)人員按工作小時數(shù)領(lǐng)取月薪;兼職推銷員的報酬按該推銷員當(dāng)月銷售額提成;銷售經(jīng)理既拿固定月薪也領(lǐng)取銷售提成。派生與繼承的實例
分析:·描述全體職員的共性〔基類〕·描述每一類特殊人員〔派生類〕雇員技術(shù)人員經(jīng)理銷售人員銷售經(jīng)理classemployee{private: char*name; //姓名
intindividualEmpNo; //個人編號
intgrade; //級別
floataccumPay; //月薪總額
staticintemployeeNo;//本公司職員編號目前最大值public: employee(); //構(gòu)造函數(shù) ~employee(); //析構(gòu)函數(shù)
voidpay(); //計算月薪函數(shù)
voidpromote(int); //升級函數(shù)
voiddisplayStatus(); //顯示人員信息};
classtechnician:publicemployee //兼職技術(shù)人員類{private:
floathourlyRate;//每小時酬金
intworkHours; //當(dāng)月工作時數(shù)public: technician(); //構(gòu)造函數(shù)
voidpay(); //計算月薪函數(shù)
voiddisplayStatus(); //顯示人員信息};新增加的成員同名覆蓋,改造基類成員
派生類的成員:1.從基類繼承的成員;2.改造基類成員;3.添加派生類新成員.同名覆蓋派生類修改基類的成員,是在派生類中聲明了一個與基類成員同名的新成員。在派生類作用域內(nèi)或者在類外通過派生類的對象直接使用這個成員名,只能訪問到派生類中聲明的同名新成員,這個新成員覆蓋了從基類繼承的同名成員,這種情況稱為同名覆蓋。
同名覆蓋#include<iostream>usingnamespacestd;classbase{public:voidfunction(){cout<<"functionofclassbase"<<endl;}};同名覆蓋classderiver:publicbase{public:voidfunction(){cout<<"functionofclassderiver"<<endl;}};intmain(){deriverobj;obj.function();}基類和派生類之間的繼承關(guān)系在面向?qū)ο蟪绦蛑?,基類的成員可以有public〔公有〕、protected〔保護(hù)〕和private〔私有〕三種訪問屬性。再次強調(diào):在基類內(nèi)部,自身成員可以對任何一個其它成員進(jìn)行訪問,但是通過基類的對象,就只能訪問基類的公有成員。派生類繼承了基類的全部數(shù)據(jù)成員和除了構(gòu)造、析構(gòu)函數(shù)之外的全部函數(shù)成員,但是這些成員的訪問屬性在派生的過程中是可以調(diào)整的。從基類繼承的成員,其訪問屬性由繼承方式控制。公有繼承(public)基類的public和protected成員的訪問屬性在派生類中保持不變,但基類的private成員不可訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能訪問基類的private成員。派生類的對象只能訪問基類的public成員。公有繼承(public)public成員 public成員protected成員 protected成員private成員public成員protected成員private成員基類派生類#include<iostream>using
namespace
std;classA{public:voidget_XY(){cout<<"Entertwonumbersofx,y:";cin>>x>>y;}voidput_XY(){cout<<"x="<<x<<",y="<<y<<'\n';}protected:intx,y;};classB:publicA{public:intget_S(){returns;};voidmake_S(){s=x*y;}; //使用基類數(shù)據(jù)成員x,yprotected:ints;};classC:publicB{public:voidget_H(){cout<<"Enteranumberofh:";cin>>h;}intget_V(){returnv;}voidmake_V(){make_S();v=get_S()*h;} //使用基類成員函數(shù)
protected:inth,v;};#include<iostream>usingnamespacestd;classA{public:voidget_XY(){cout<<"Entertwonumbersofx,y:";cin>>x>>y;}voidput_XY(){cout<<"x="<<x<<",y="<<y<<'\n';}protected:intx,y;};classB
:publicA{public:intget_S(){returns;};voidmake_S(){s=x*y;};//使用基類數(shù)據(jù)成員x,yprotected:ints;};classC:publicB{public:voidget_H(){cout<<"Enteranumberofh:";cin>>h;}intget_V(){returnv;}voidmake_V(){make_S();v=get_S()*h;} //使用基類成員函數(shù)
protected:inth,v;};classAclassC:publicBclassB:publicA#include<iostream>usingnamespacestd;classA{public:voidget_XY(){cout<<"Entertwonumbersofx,y:";cin>>x>>y;}voidput_XY(){cout<<"x="<<x<<",y="<<y<<'\n';}
protected:intx,y;};classB:publicA{public:intget_S(){returns;};voidmake_S(){s=x*y;};//使用基類數(shù)據(jù)成員x,y
protected:ints;};classC:publicB{public:voidget_H(){cout<<"Enteranumberofh:";cin>>h;}intget_V(){returnv;}voidmake_V(){make_S();v=get_S()*h;} //使用基類成員函數(shù)
protected:inth,v;};classAclassC:publicBclassB:publicA保護(hù)數(shù)據(jù)成員在類層次中可見voidmain(){AobjA;
BobjB;
CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}7.2.1訪問控制objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCxyshvvoidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";
objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}對objA的數(shù)據(jù)成員操作7.2.1訪問控制objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCxyshvvoidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";
objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}調(diào)用基類A成員函數(shù)對objB的數(shù)據(jù)成員操作7.2.1訪問控制objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCxyshvvoidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";objB.get_XY();
objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}調(diào)用派生類B成員函數(shù)對objB的數(shù)據(jù)成員操作objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCxyshvvoidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";
objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}調(diào)用基類A成員函數(shù)對objC的數(shù)據(jù)成員操作7.2.1訪問控制objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCxyshvvoidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();
objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjC調(diào)用派生類C成員函數(shù)對objC的數(shù)據(jù)成員操作xyshv#include<iostream>usingnamespacestd;classA{public: A(){x=1;} intout(){returnx;} voidaddX(){x++;}private: intx;};classB:publicA{public: B(){y=1;} intout(){returny;} voidaddY(){y++;}private: inty;};voidmain(){Aa;Bb;b.addX();b.addY();cout<<"a.x="<<a.out()<<endl;cout<<"b.x="<<b.A::out()<<endl;cout<<"b.y="<<b.out()<<endl;}classB:publicAclassA基類的私有數(shù)據(jù)成員不能在派生類中直接訪問但派生類對象建立私有數(shù)據(jù)空間
b.xa.xb.yclassBase{public:voidfoo(intf){bar=f;}//….protected:intbar;doublefoo_bar;};classDerived:publicBase{public:voidfoo(stringf){bar=f;}boolbar(Base*pb);voidfootbar();//…..protected:stringbar;};voidDerived::footbar(){bar=1024;}boolDerived::bar(Base*pb){returnfoo_bar==pb->foo_bar;}intmain(){Derivedd;d.foo(“1024”);}找出錯誤,并說明原因私有繼承(private)基類的public和protected成員都以private身份出現(xiàn)在派生類中,但基類的private成員不可直接訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能訪問基類的private成員。派生類的對象不能訪問基類中的任何成員。私有繼承(private)public成員protected成員private成員public成員protected成員private成員基類派生類private成員private成員#include<iostream>using
namespace
std;classA{public:voidget_XY(){cout<<"Entertwonumbersofx,y:";cin>>x>>y;}voidput_XY(){cout<<"x="<<x<<",y="<<y<<'\n';}protected:intx,y;};classB:privateA{public:intget_S(){returns;};voidmake_S(){s=x*y;}; protected:ints;};classC:publicB{public:voidget_H(){cout<<"Enteranumberofh:";cin>>h;}intget_V(){returnv;}voidmake_V(){make_S();v=get_S()*h;}
protected:inth,v;};voidmain(){AobjA;BobjB;CobjC;cout<<"Itisobject_A:\n";objA.get_XY();objA.put_XY();cout<<"Itisobject_B:\n";
objB.get_XY();objB.make_S();cout<<"S="<<objB.get_S()<<endl;cout<<"Itisobject_C:\n";objC.get_XY();objC.get_H();objC.make_V();cout<<"V="<<objC.get_V()<<endl;}找出錯誤的地方保護(hù)繼承(protected)基類的public和protected成員都以protected身份出現(xiàn)在派生類中,但基類的private成員不可訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能訪問基類的private成員。派生類的對象不能訪問基類中的任何成員.保護(hù)繼承(protected)public成員protected成員private成員public成員protected成員private成員基類派生類protected成員protected成員保護(hù)繼承(protected)對建立其所在類對象的模塊來說,它與private成員的性質(zhì)相同。對于其派生類來說,它與public成員的性質(zhì)相同。既實現(xiàn)了數(shù)據(jù)隱藏,又方便繼承,實現(xiàn)代碼重用。private成員和protected成員的區(qū)別無論何種繼承方式,private成員是無法在派生類中被直接訪問的。而對于protected成員,根據(jù)不同的派生方式,protected成員的直接訪問特性可以被〔或不被〕傳遞到派生類的派生類中。7.2.3派生類中的靜態(tài)成員
基類定義的靜態(tài)成員,將被所有派生類共享.根據(jù)靜態(tài)成員自身的訪問特性和派生類的繼承方式,在類層次體系中具有不同的訪問性質(zhì).
派生類中訪問靜態(tài)成員,用以下形式顯式說明:類名::成員或通過對象訪問 對象名.成員派生類中的靜態(tài)成員#include<iostream>usingnamespacestd;{public:
staticvoidAdd(){i++;}
staticinti;voidout(){cout<<"statici="<<i<<endl;}};intB::i=0;{public:voidf(){i=5;Add();B::i++;B::Add();}};voidmain(){Bx;Dy;x.Add();x.out();y.f();cout<<"statici="<<B::i<<endl;cout<<"statici="<<x.i<<endl;
//cout<<"statici="<<y.i<<endl;}靜態(tài)成員函數(shù)classBclassD:privateB靜態(tài)數(shù)據(jù)成員#include<iostream>usingnamespacestd;classB{public:
staticvoidAdd(){i++;}
staticinti;voidout(){cout<<"statici="<<i<<endl;}};intB::i=0;classD:privateB{public:voidf(){i=5;
Add();B::i++;B::Add();}};voidmain(){Bx;Dy;x.Add();x.out();y.f();cout<<"statici="<<B::i<<endl;cout<<"statici="<<x.i<<endl;
//cout<<"statici="<<y.i<<endl;}i是類D的私有靜態(tài)數(shù)據(jù)成員類中可見Add()是類D的私有靜態(tài)成員函數(shù)類中可調(diào)用#include<iostream>usingnamespacestd;classB{public:
staticvoidAdd(){i++;}
staticinti;voidout(){cout<<"statici="<<i<<endl;}};intB::i=0;classD:privateB{public:voidf(){i=5;Add();B::i++;B::Add();}};voidmain(){Bx;Dy;x.Add();x.out();y.f();cout<<"statici="<<B::i<<endl;cout<<"statici="<<x.i<<endl;cout<<"statici="<<y.i<<endl;}〔可以換成public繼承〕訪問B類的靜態(tài)成員訪問B類的靜態(tài)數(shù)據(jù)成員通過B類對象訪問靜態(tài)數(shù)據(jù)成員派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù)基類的構(gòu)造函數(shù)不被繼承,派生類中需要聲明自己的構(gòu)造函數(shù)。聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進(jìn)行初始化,對繼承來的基類成員的初始化,自動調(diào)用基類構(gòu)造函數(shù)完成。派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)傳遞參數(shù)派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù)析構(gòu)函數(shù)也不被繼承,派生類自行聲明聲明方法與一般〔無繼承關(guān)系時〕類的析構(gòu)函數(shù)相同。不需要顯式地調(diào)用基類的析構(gòu)函數(shù),系統(tǒng)會自動隱式調(diào)用。析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反。簡單的派生類的構(gòu)造函數(shù)簡單的派生類只有一個基類,而且只有一級派生(只有直接派生類,沒有間接派生類),在派生類的數(shù)據(jù)成員中不包含基類的對象。
簡單派生類的構(gòu)造函數(shù)的一般形式為
派生類構(gòu)造函數(shù)名〔總參數(shù)列表〕:基類構(gòu)造函數(shù)名〔參數(shù)列表〕{派生類中新增數(shù)據(jù)成員初始化語句}【例】簡單的派生類的構(gòu)造函數(shù)。#include<iostream>#include<string>usingnamespacestd;classStudent//聲明基類Student{public:Student(intn,stringnam,chars)//基類構(gòu)造函數(shù){num=n;name=nam;sex=s;}~Student(){}//基類析構(gòu)函數(shù)protected://保護(hù)局部intnum;stringname;charsex;};classStudent1:publicStudent//聲明派生類Student1{public://派生類的公用局部Student1(intn,stringnam,chars,inta,stringad):Student(n,nam,s)//派生類構(gòu)造函數(shù){age=a;//在函數(shù)體中只對派生類新增的數(shù)據(jù)成員初始化addr=ad;}voidshow(){cout<<″num:″<<num<<endl;cout<<″name:″<<name<<endl;cout<<″sex:″<<sex<<endl;cout<<″age:″<<age<<endl;cout<<″address:″<<addr<<endl<<endl;}~Student1(){}//派生類析構(gòu)函數(shù)private://派生類的私有局部intage;stringaddr;};intmain(){Student1stud1(10010,″Wang-li″,′f′,19,″115BeijingRoad,Shanghai″);Student1stud2(10011,″Zhang-fun″,′m′,21,″213ShanghaiRoad,Beijing″);stud1.show();//輸出第一個學(xué)生的數(shù)據(jù)
stud2.show();//輸出第二個學(xué)生的數(shù)據(jù)
return0;}運行結(jié)果為num:10010name:Wang-lisex:faddress:115BeijingRoad,Shanghainum:10011name:Zhang-funsex:maddress:213ShanghaiRoad,Beijing派生類在建立對象時調(diào)用構(gòu)造函數(shù),其實參傳遞給形參的形式如下:派生類的構(gòu)造函數(shù)也可以只在類體中聲明,而在類外定義。
【例】
類內(nèi)聲明的形式如下:Student1(intn,stringnam,chars,inta,stringad);類外定義派生類構(gòu)造函數(shù):Student1∷Student1(intn,stringnam,chars,inta,stringad):Student(n,nam,s){age=a;addr=ad;}
注意:在類中對派生類構(gòu)造函數(shù)作聲明時,不包括基類構(gòu)造函數(shù)名及其參數(shù)表列。只在定義函數(shù)時才將它列出。在調(diào)用派生類構(gòu)造函數(shù)時,基類構(gòu)造函數(shù)的實參也可以不從派生類構(gòu)造函數(shù)的總參數(shù)表中傳遞過來,而直接使用常量或全局變量。
【例】派生類構(gòu)造函數(shù)首行可寫成以下形式:Student1(intn,stringnam,chars,inta,stringad):Student(10010,nam,s)派生類構(gòu)造函數(shù)的定義也可以采用參數(shù)初始化表的形式。
【例】Student1(intn,stringnam,chars,inta,stringad):Student(n,nam,s),age(a),addr(ad){}在建立派生類對象時,執(zhí)行構(gòu)造函數(shù)的順序是:①先調(diào)用基類構(gòu)造函數(shù);②再執(zhí)行派生類構(gòu)造函數(shù)本身(即派生類構(gòu)造函數(shù)的函數(shù)體)。在派生類對象釋放時,先執(zhí)行派生類析構(gòu)函數(shù),再執(zhí)行其基類析構(gòu)函數(shù)。有子對象的派生類的構(gòu)造函數(shù)類的數(shù)據(jù)成員中可以包含類的對象,即對象中的對象,稱為子對象(subobject)。派生類構(gòu)造函數(shù)的任務(wù)應(yīng)該包括3個局部:①對基類數(shù)據(jù)成員初始化;②對子對象數(shù)據(jù)成員初始化;③對派生類數(shù)據(jù)成員初始化。定義有子對象的派生類構(gòu)造函數(shù)的一般形式為派生類構(gòu)造函數(shù)名〔總參數(shù)表列〕:基類構(gòu)造函數(shù)名〔參數(shù)表列〕,子對象名(參數(shù)表列){派生類中新增數(shù)成員據(jù)成員初始化語句}【例】包含子對象的派生類的構(gòu)造函數(shù)。#include<iostream>#include<string>usingnamespacestd;classStudent//聲明基類{public://公用局部Student(intn,stringnam)//基類構(gòu)造函數(shù){num=n;name=nam;}voiddisplay()//成員函數(shù),輸出基類數(shù)據(jù)成員{cout<<″num:″<<num<<endl<<″name:″<<name<<endl;}protected://保護(hù)局部intnum;stringname;};classStudent1:publicStudent//聲明公用派生類Student1{public:
Student1(intn,stringnam,intn1,stringnam1,inta,stringad):Student(n,nam),monitor(n1,nam1)//派生類構(gòu)造函數(shù)
{age=a;addr=ad;}voidshow(){cout<<″Thisstudentis:″<<endl;display();//輸出num和namecout<<″age:″<<age<<endl;//輸出agecout<<″address:″<<addr<<endl<<endl;//輸出addr}voidshow_monitor()//成員函數(shù),輸出子對象
{cout<<endl<<″Classmonitoris:″<<endl;monitor.display();//調(diào)用基類成員函數(shù)
}private://派生類的私有數(shù)據(jù)
Studentmonitor;//定義子對象(班長)intage;stringaddr;};intmain(){Student1stud1(10010,″Wang-li″,10001,″Li-sun″,19,″115BeijingRoad,Shanghai″);stud1.show();//輸出學(xué)生的數(shù)據(jù)
stud1.show_monitor();//輸出子對象的數(shù)據(jù)return0;}運行時的輸出如下:
Thisstudentis:num:10010name:Wang-liage:19address:115BeijingRoad,ShanghaiClassmonitoris:num:10001name:Li-sun派生類構(gòu)造函數(shù)中的基類構(gòu)造函數(shù)和子對象的參數(shù)列表的次序可以是任意的,編譯系統(tǒng)會根據(jù)參數(shù)名來確立它們的傳遞關(guān)系的。執(zhí)行派生類構(gòu)造函數(shù)的順序是:①調(diào)用基類構(gòu)造函數(shù),對基類數(shù)據(jù)成員初始化;②調(diào)用子對象構(gòu)造函數(shù),對子對象數(shù)據(jù)成員初始化;③再執(zhí)行派生類構(gòu)造函數(shù)本身,對派生類數(shù)據(jù)成員初始化。多層派生時的構(gòu)造函數(shù)一個類不僅可以派生出一個派生類,派生類還可以繼續(xù)派生,形成派生的層次結(jié)構(gòu)?!纠慷嗉壟缮闆r下派生類的構(gòu)造函數(shù)。#include<iostream>#include<string>usingnamespacestd;classStudent//聲明基類{public://公用局部Student(intn,stringnam)//基類構(gòu)造函數(shù){num=n;name=nam;}voiddisplay()//輸出基類數(shù)據(jù)成員{cout<<″num:″<<num<<endl;cout<<″name:″<<name<<endl;}protected://保護(hù)局部intnum;//基類有兩個數(shù)據(jù)成員stringname;};classStudent1:publicStudent//聲明公用派生類Student1{public:Student1(intn,charnam[10],inta):Student(n,nam)//派生類構(gòu)造函數(shù)
{age=a;}//在此處只對派生類新增的數(shù)據(jù)成員初始化
voidshow()//輸出num,name和age{display();//輸出num和namecout<<″age:″<<age<<endl;}private://派生類的私有數(shù)據(jù)
intage;//增加一個數(shù)據(jù)成員
};classStudent2:publicStudent1//聲明間接公用派生類Student2{public:
Student2(intn,stringnam,inta,ints):Student1(n,nam,a){score=s;}voidshow_all()//輸出全部數(shù)據(jù)成員{show();//輸出num和namecout<<″score:″<<score<<endl;//輸出age}private:intscore;//增加一個數(shù)據(jù)成員
};intmain(){Student2stud(10010,″Li″,17,89);stud.show_all();//輸出學(xué)生的全部數(shù)據(jù)return0;}運行時的輸出如下:
num:10010name:Liage:17score:89上例派生關(guān)系如以下圖所示。在執(zhí)行Student2構(gòu)造函數(shù)時,先調(diào)用Student1構(gòu)造函數(shù);在執(zhí)行Student1構(gòu)造函數(shù)時,先調(diào)用基類Student構(gòu)造函數(shù)。初始化的順序是:①先初始化基類的數(shù)據(jù)成員num和name。②再初始化Student1的數(shù)據(jù)成員age。③最后再初始化Student2的數(shù)據(jù)成員score。派生類構(gòu)造函數(shù)的特殊形式在使用派生類構(gòu)造函數(shù)時,有以下特殊的形式:
①
當(dāng)不需要對派生類新增的成員進(jìn)行任何初始化操作時,派生類構(gòu)造函數(shù)的函數(shù)體可以為空,即構(gòu)造函數(shù)是空函數(shù)。此派生類構(gòu)造函數(shù)的作用只是為了將參數(shù)傳遞給基類構(gòu)造函數(shù)和子對象,并在執(zhí)行派生類構(gòu)造函數(shù)時調(diào)用基類構(gòu)造函數(shù)和子對象構(gòu)造函數(shù)。classApublic:{public:B(intx):A(x){}A(intx){n=x;}};private:intn;};ClassB:publicA{
②
如果在基類中沒有定義構(gòu)造函數(shù),或定義了沒有參數(shù)的構(gòu)造函數(shù),那么在定義派生類構(gòu)造函數(shù)時可不寫基類構(gòu)造函數(shù)。調(diào)用派生類構(gòu)造函數(shù)時系統(tǒng)會自動首先調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。classApublic:{public:B(inty1){y=y1;}A(intx=0){n=x;}private:private:inty;};intn;};ClassB:publicA{如果在基類中既定義無參的構(gòu)造函數(shù),又定義了有參的構(gòu)造函數(shù),那么在定義派生類構(gòu)造函數(shù)時,既可以包含基類構(gòu)造函數(shù)及其參數(shù),也可以不包含基類構(gòu)造函數(shù)。在調(diào)用派生類構(gòu)造函數(shù)時,根據(jù)構(gòu)造函數(shù)的內(nèi)容決定調(diào)用基類的有參的構(gòu)造函數(shù)還是無參的構(gòu)造函數(shù)。#include<iostream>usingnamespacestd;classBASE{public:BASE(){cout<<"\nConstructBASE!";}~BASE(){cout<<"\nDestructBASE!";}};
classDERIVE:publicBASE{public:DERIVE(){cout<<"\nConstructDERIVE!";}~DERIVE(){cout<<"\nDestructDERIVE!";}//private://BASEderive_base;};voidmain(){BASEbase;DERIVEderive;}多繼承class<派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…{//以下定義派生類新成員private://私有成員說明
...public://公有成員說明
...protected://保護(hù)成員說明
...};多個基類派生一個類多繼承Circle類Point類
Radius類
組合例:
先定義“點”類Point和“半徑”類Radius,再由Point類和Radius類多重派生出“圓”類Circle。#include<iostream>usingnamespacestd;#definePI3.14159classPoint{protected:
//A intx,y;public: Point(inta=0,intb=0){x=a;y=b;} voidShowPoint(){cout<<"Point:("<<x<<','<<y<<")\n";} intGetx(){returnx;} intGety(){returny;} voidSetxy(inta,intb){x=a;y=b;}};classRadius{protected:
//B intr;public: Radius(intra=0){r=ra;} voidSetr(intra){r=ra;} intGetr() {returnr;}};classCircle:publicPoint,publicRadius
//C{public: Circle(intx,inty,intra):Point(x,y),Radius(ra)
//D {} doubleArea() {returnPI*r*r;}//直接訪問基類的保護(hù)成員
voidMove(intx_offset,inty_offset) {x+=x_offset;y+=y_offset;}
voidShowCircle() { ShowPoint(); cout<<"Radius:"<<r<<'\t'; cout<<"Area:"<<Area()<<endl; }};voidmain(){ Circlec(1,1,1); c.ShowCircle(); c.Move(1,2); c.ShowCircle(); c.Setxy(4,5); c.Setr(2); c.ShowCircle();}多繼承說明:構(gòu)造函數(shù)調(diào)用的順序是先執(zhí)行基類的構(gòu)造函數(shù),再執(zhí)行派生類自己的構(gòu)造函數(shù)的函數(shù)體。析構(gòu)函數(shù)順序和構(gòu)造函數(shù)調(diào)用順序相反調(diào)用基類的構(gòu)造函數(shù)的順序并不是D行的書寫順序決定的,而是C行定義派生類時的派生順序決定的,即使將D行改寫成Circle(intx,inty,intra):Radius(ra),Point(x,y),程序的運行結(jié)果依然不變。
一般地,派生類成員的訪問是唯一的。但是在多繼承的情況下,可能出現(xiàn)派生類對其類成員訪問的不唯一性,即二義性。下面是出現(xiàn)二義性的兩種情況:1、調(diào)用不同類的具有相同名字成員時可能出現(xiàn)二義性,例如:
#include<iostream> usingnamespacestd;classA{public:voidf();};
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年銷售員績效考核與獎懲制度勞務(wù)用工協(xié)議3篇
- 建筑工程供貨合同
- 2025年校園運動場地設(shè)施采購及施工合同2篇
- 機房優(yōu)先施工方案
- 二零二五年度5G通信技術(shù)應(yīng)用合同4篇
- 2025年度個人旅游規(guī)劃師雇傭服務(wù)協(xié)議4篇
- 二零二五版美發(fā)店合伙人創(chuàng)業(yè)投資合作合同4篇
- 齒輪鍛件課程設(shè)計
- 課課程設(shè)計要寫哪幾步
- 基礎(chǔ)土方回填施工方案
- 2024企業(yè)答謝晚宴會務(wù)合同3篇
- 中華人民共和國文物保護(hù)法
- 節(jié)前物業(yè)安全培訓(xùn)
- 高甘油三酯血癥相關(guān)的器官損傷
- 部編二上語文第四單元美麗中國 公開課一等獎創(chuàng)新教學(xué)設(shè)計
- 病理生理學(xué)專業(yè)的疾病生理和新藥研發(fā)
- 油畫人體200張東方姑娘的極致美
- 人教A版必修五《斐波那契數(shù)列》教案及教學(xué)反思
- 風(fēng)電工程需要編寫的專項施工方案及危大工程目錄
- 商業(yè)計劃書(BP)財務(wù)計劃風(fēng)險控制資本退出與附錄的撰寫秘籍
- 七年級下冊《Reading 1 A brave young man》優(yōu)質(zhì)課教案牛津譯林版-七年級英語教案
評論
0/150
提交評論