C 面向?qū)ο蟪绦蛟O(shè)計(第二版)課件 第5章繼承_第1頁
C 面向?qū)ο蟪绦蛟O(shè)計(第二版)課件 第5章繼承_第2頁
C 面向?qū)ο蟪绦蛟O(shè)計(第二版)課件 第5章繼承_第3頁
C 面向?qū)ο蟪绦蛟O(shè)計(第二版)課件 第5章繼承_第4頁
C 面向?qū)ο蟪绦蛟O(shè)計(第二版)課件 第5章繼承_第5頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

面向?qū)ο蟪绦蛟O(shè)計第5章繼承主要內(nèi)容●5.1繼承與派生●5.2派生類的訪問控制●

5.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)●5.4多繼承●

5.5虛基類●5.6賦值兼容性規(guī)則5.1繼承與派生01繼承與派生概念建筑工業(yè)建筑單層廠房多層廠房民用建筑住宅平房多層高層商場醫(yī)院學(xué)校地下建筑人防工程地下車庫繼承和派生的概念源于人們對客觀世界的認識過程是自然界普遍存在的一種現(xiàn)象。許多事物之間存在著繼承的關(guān)系。上層:基類;下層:派生類。圖5.1建筑類的繼承與派生關(guān)系抽象程度最高,具有一般意義的概念具體化、特殊化抽象化01

繼承與派生的概念classPersonclassStudentPropertiesNameGenderCityOperationsSpeak()GetInformation()PropertiesSNOSchoolNameGenderCityOperationsHaveLesson()Speak()GetInformation()那個具有一般性?哪個更具有特殊性、更具體?02繼承的種類每一個派生類有且僅有一個基類,派生類可以看作是基類的特例單繼承:多繼承:一個派生類可以有多個基類,它繼承了多個基類的特性。圖5.2單繼承、多繼承和多層繼承以派生類作為基類再派生出派生類。多級繼承:02繼承的種類(1)繼承關(guān)系可以是多級的,即可以有類Y繼承類X和類Z繼承類Y同時存在。(2)不允許循環(huán)繼承。(3)基類中能夠被繼承的部分只能是公有成員和保護成員,私有成員不能被繼承。C++的繼承關(guān)系有以下幾個特點03派生類的聲明class<派生類名>:<繼承方式><基類名>{<派生類新定義成員>;};說明:(1)派生類定義中,繼承方式只限定緊跟其后的那個基類。如果不顯式給出繼承方式,系統(tǒng)默認為私有繼承。(2)派生方式關(guān)鍵字為private、public和protected。缺省的繼承方式是私有繼承。繼承方式規(guī)定了派生類成員和類外對象訪問基類成員的權(quán)限。(3)派生類新定義的成員是指繼承過程中新增加的數(shù)據(jù)成員和成員函數(shù)。

單繼承的定義03派生類的聲明

多繼承的定義格式如下:說明:(1)每一個繼承方式對應(yīng)的是緊接其后給出的基類。(2)必須給每個基類指定一種此派生類從這個基類繼承的繼承方式,(3)如果缺省,相應(yīng)的繼承方式則取私有繼承,而不是和前一個基類取相同的繼承方式。class派生類名:繼承方式1基類名1,繼承方式2基類名2,…{private:

派生類的私有數(shù)據(jù)和函數(shù)

public:

派生類的公有數(shù)據(jù)和函數(shù)

protected:

派生類的保護數(shù)據(jù)和函數(shù)};03派生類的聲明【例5-1】在普通的時鐘類Clock基礎(chǔ)上派生出鬧鐘類AlarmClock。classAlarmClock:

publicClock{private:intAH,AM;//響鈴的時間boolOpenAlarm;//是否關(guān)閉鬧鐘public:SetAlarm(intAH,intAM);//設(shè)置響鈴時間SwitchAlarm(boolOpen=true);//打開/關(guān)閉鬧鈴ShowTime();//顯示當(dāng)前時間與鬧鈴時間};派生類AlarmClock的成員構(gòu)成圖類名成員名AlarmClock::Clock::H,M,SSetTime()ShowTime()AH,AM,OpenAlarmSetAlarm()SwitchAlarm()ShowTime()#include<iostream>usingnamespacestd;classClock{private:intH,M,S;public:voidSetTime(intH=0,intM=0,intS=0);voidShowTime();Clock(intH=0,intM=0,intS=0);~Clock();};03派生類的聲明派生類的生成過程:(1)吸收基類成員

基類的全部成員被派生類繼承,作為派生類成員的一部分。(2)改造基類成員

派生類根據(jù)實際情況對繼承自基類的某些成員進行限制和改造。(同名覆蓋:如ShowTime())(3)添加新成員

派生類在繼承基類成員的基礎(chǔ)之上,根據(jù)派生類的實際需要,增加一些新的數(shù)據(jù)成員和函數(shù)成員,以描述某些新的屬性和行為。未被繼承的部分

(private)

被繼承的部分

(public,protected)

被繼承的部分

新增加或改變的部分基類派生類總結(jié)5.2派生類的訪問控制1301公有繼承方式三種繼承方式:公有繼承:public私有繼承:private保護繼承:protect1..派生類的繼承方式14不同繼承方式的影響主要體現(xiàn)在:派生類成員對基類成員的訪問權(quán)限通過派生類對象對基類成員的訪問權(quán)限01公有繼承方式繼承不影響基類的數(shù)據(jù)成員分配,不破壞基類的獨立性;所有的數(shù)據(jù)成員都占有內(nèi)存,靜態(tài)數(shù)據(jù)成員被唯一地放置在全局數(shù)據(jù)區(qū)。派生類對象占有的內(nèi)存是基類對象占有的內(nèi)存和派生類新增數(shù)據(jù)成員的內(nèi)存之和。類層次本身的訪問控制屬性和繼承方式對于對象的內(nèi)存分配無影響。幾個主要的概念:1501公有繼承方式

(1)

公有繼承:public基類的public和protected成員的訪問屬性在派生類中保持不變,但基類的private成員不可直接訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員。通過派生類的對象只能訪問基類的public成員。1601

公有繼承方式【例5-2】用學(xué)生檔案類Student派生學(xué)生的成績類Score

#include<iostream>usingnamespacestd;classStudent{private:intNo;

protected:intAge;

voidSetNo(intno){this->No=no;}

voidSetAge(intage){this->Age=age;}

voidSetSex(charsex){this->Sex=sex;}

public:charSex;

intGetNo()const{returnNo;}

intGetAge()const{returnAge;}

charGetSex()const{returnSex;}

voidShow()

{cout<<"No="<<No<<'\t'<<"Age="<<Age<<'\t'<<"Sex="<<Sex<<endl;}voidSetStudent(intno,intage,charsex){

SetNo(no);SetAge(age);SetSex(sex); }};classScore:publicStudent {private:intPhi,Math; public:intSetPhi(intPhi){returnthis->Phi=Phi;}intSetMath(intMath){returnthis->Math=Math;}voidShow(){cout<<"No="<<GetNo()<<'\t'<<"Age="<<Age<<'\t'<<"Sex="<<Sex<<'\t'<<"Phi="<<Phi<<'\t'<<"Math="<<Math<<endl;}};5-1.mp41701公有繼承方式intmain(){Scores;s.SetStudent(101,20,'M');s.SetPhi(90);s.SetMath(80);s.Show();cout<<"No="<<s.GetNo()<<'\t'<<"Age="<<s.GetAge()

<<'\t’<<"Sex="<<s.Sex<<endl;return0;}【例5-2】續(xù)No=101Age=20Sex=MPhi=90Math=80No=101Age=20Sex=M運行結(jié)果:5-1.mp41802私有繼承方式私有繼承(private)基類的public和protected成員都以private身份出現(xiàn)在派生類中,但基類的private成員不可直接訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員。通過派生類的對象不能直接訪問基類中的任何成員。如何在私有繼承下訪問基類的公有成員思考一下:1902私有繼承方式#include<iostream>usingnamespacestd;classBase{public:ints;Base(){s1=1;s2=2;s3=3;s=4;}voidfun(){cout<<s<<endl;//正確

cout<<s1<<endl;//正確

cout<<s2<<endl;//正確

cout<<s3<<endl;//正確

}public:ints1;protected:ints2;private:ints3;};classDerived:privateBase{public:ints;Derived(inti){Base();s=i;}voidfun(){cout<<s<<endl;//正確,public成員。

cout<<s1<<endl;//正確,基類public成員,在派生類中變成了private,可以被派生類訪問。

cout<<s2<<endl;//正確,基類的protected成員,在派生類中變成了private,可以被派生類訪問。

//cout<<s3<<endl;//錯誤,基類的private成員不能被派生類訪問。

}};intmain(){Derivedp(50);cout<<p.s<<endl;//正確。public成員

//cout<<p.s1<<endl;//錯誤,private成員不能在類外訪問。

//cout<<p.s2<<endl;//錯誤,private成員不能在類外訪問。

//cout<<p.s3<<endl;//錯誤,private成員不能在類外訪問。

return0;205-2.mp403保護繼承方式基類的public和protected成員都以protected身份出現(xiàn)在派生類中,但基類的private成員不可直接訪問。派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員。通過派生類的對象不能直接訪問基類中的任何成員保護繼承:protected2103

保護繼承方式【例5-4】保護繼承。#include<iostream>usingnamespacestd;classPoint{public:voidfun1()

{

cout<<"Point類中的公有成員函數(shù)"<<endl;

}protected:voidfun2(){

cout<<"Point類中的保護成員函數(shù)"<<endl;}};classRectangle:protectedPoint{ //Rectangle新添加的成員};classSquare:publicRectangle{public:voidfun(){

fun1();

fun2();}};intmain(){Squares;s.fun();return0;}Point類中的公有成員函數(shù)Point類中的保護成員函數(shù)225-3.mp4派生類的訪問控制總結(jié)表5-1不同繼承方式的基類和派生類特性235.3派生類的構(gòu)造和析構(gòu)函數(shù)2401派生類的構(gòu)造函數(shù)派生類中需要聲明自己的構(gòu)造函數(shù)。聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進行初始化,對繼承來的基類成員的初始化,自動調(diào)用基類構(gòu)造函數(shù)完成。派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)傳遞參數(shù)1、派生類的構(gòu)造函數(shù)2、派生類構(gòu)造函數(shù)的定義派生類名(參數(shù)總表):基類名1(參數(shù)表1),…,基類名m(參數(shù)表m),

成員對象名1(成員對象參數(shù)表1),…,成員對象名n(成員對象參數(shù)表n)

{

派生類新增成員的初始化;

}基類成員的初始化表3、派生類構(gòu)造函數(shù)調(diào)用規(guī)則單繼承時,派生類構(gòu)造函數(shù)調(diào)用的一般次序如下:

(1)調(diào)用基類構(gòu)造函數(shù)。(2)調(diào)用內(nèi)嵌成員對象的構(gòu)造函數(shù),調(diào)用順序取決于它們在類中定義的順序。(3)派生類自己的構(gòu)造函數(shù)。

派生類構(gòu)造函數(shù)的總參數(shù)表中定義的參數(shù)個數(shù)等于基類中構(gòu)造函數(shù)參數(shù)的個數(shù)和派生類中新增數(shù)據(jù)成員的個數(shù)之和,新增成員包括普通數(shù)據(jù)成員和子對象數(shù)據(jù)成員。2501派生類的構(gòu)造函數(shù)【例5-5】單繼承機制下構(gòu)造函數(shù)的調(diào)用順序。#include<iostream>usingnamespacestd;classBaseclass{

public:Baseclass(inti)

{

a=i;cout<<"constructingBaseclassa="<<a<<endl;

}

private:inta; };classDerivedclass:publicBaseclass{public:

Derivedclass(inti,intj);private:intb;};Derivedclass::Derivedclass(inti,intj):Baseclass(i){

b=j;cout<<"constructingDerivedclassb="<<b<<endl;}intmain(){Derivedclassx(5,6);

return0;}constructingBaseclassa=5constructingDerivedclassb=6程序輸出結(jié)果為:2602派生類的組合當(dāng)一個類既是派生類同時又包含嵌入對象時,構(gòu)造函數(shù)調(diào)用次序:調(diào)用基類的構(gòu)造函數(shù)按類聲明中嵌入對象出現(xiàn)的次序調(diào)用嵌入對象的構(gòu)造函數(shù)執(zhí)行派生類的構(gòu)造函數(shù)通過初始化列表向嵌入對象的構(gòu)造函數(shù)傳遞參數(shù)。組合的概念:一個類中的數(shù)據(jù)成員包含另一個類的對象。2702派生類的組合【例5-6】包括派生類新增的數(shù)據(jù)中有成員對象時,其構(gòu)造函數(shù)的調(diào)用順序。#include<iostream>usingnamespacestd;classBase1//基類{public:Base1(inti){a=i;cout<<"constructingBase1a="<<a<<endl;}private:inta; };classBase2{public:Base2(inti){b=i;cout<<"constructingBase2b="<<b<<endl;}private:intb; };classBase3{public:Base3(inti){c=i; cout<<"constructingBase3c="<<c<<endl;}private:intc; };classDerivedclass:publicBase1{public:Derivedclass(inti,intj,intk,intm);private:intd;Base2f;Base3g;};2802派生類的組合Derivedclass::Derivedclass(inti,intj,intk,intm):Base1(i),g(j),f(k){d=m;cout<<"constructingDerivedclassd="<<d<<endl;}intmain(){Derivedclassx(5,6,7,8);return0;}constructingBase1a=5constructingBase2b=7constructingBase3c=6constructingDerivedclassd=8Pressanykeytocontinue注意:成員對象f和g的調(diào)用順序取決于它們有派生類中被聲明的順序,與它們在成員初始化列表中的順序無關(guān)。程序運行結(jié)果:2903

派生類析構(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ù)相反。(1)首先調(diào)用派生類的析構(gòu)函數(shù)(清理派生類新增成員);(2)如果派生類中有成員對象,再調(diào)用派生類中成員對象所在類的析構(gòu)函數(shù)(清理派生類新增的成員對象);(3)再調(diào)用普通基類的析構(gòu)函數(shù)(清理從基類繼承來的基類對象);(4)最后調(diào)用虛基類的析構(gòu)函數(shù)。(虛基類的知識在后面講解)析構(gòu)函數(shù)調(diào)用規(guī)則如下:析構(gòu)函數(shù)執(zhí)行順序和構(gòu)造函數(shù)正好相反先自己(派生類本身)再客人(內(nèi)嵌對象)后祖先(基類)?;叵胍幌聵?gòu)造函數(shù)的調(diào)用次序?3003

派生類析構(gòu)函數(shù)【例5-8】派生類析構(gòu)函數(shù)的調(diào)用順序。#include<iostream>usingnamespacestd;classBase1//基類{public:Base1(inti){

a=i;cout<<“constructingBase1a=”<<a<<endl;

}

~Base1(){

cout<<"destructingBase1"<<endl; } private:inta;};classBase2//基類Base2{public:Base2(inti)//構(gòu)造函數(shù) { b=i;cout<<"constructingBase2b="<<b<<endl; } ~Base2()//析構(gòu)函數(shù) {cout<<"destructingBase2"<<endl; }private:intb; };315-4.mp403

派生類析構(gòu)函數(shù)classBase3//子對象f所屬類{public:Base3(inti)//構(gòu)造函數(shù) { c=i;cout<<"constructingBase3c="<<c<<endl; } ~Base3()//析構(gòu)函數(shù) { cout<<"destructingBase3"<<endl; }private:intc;};classBase4//子對象g所屬類{public:Base4(inti)//構(gòu)造函數(shù) { d=i;cout<<"constructingBase4d="<<d<<endl; } ~Base4()//析構(gòu)函數(shù) { cout<<"destructingBase4"<<endl; }private:intd;};3203

派生類析構(gòu)函數(shù)classDerivedclass:publicBase1,publicBase2{public:Derivedclass(inti,intj,intk,intm,intn);~Derivedclass();private:inte;

Base3f;Base4g;

};Derivedclass::Derivedclass(inti,intj,intk,intm,intn):Base1(i),Base2(j),f(k),g(m){

e=n;cout<<"constructingDerivedclasse="<<e<<endl;}Derivedclass::~Derivedclass()//派生類析構(gòu)函數(shù){cout<<"destructingDerivedclass"<<endl;}contructingBase1a=5contructingBase2b=6contructingBase3c=7contructingBase4d=8contructingDerivedclasse=9destructingDerivedclassdestructingBase4destructingBase3destructingBase2destructingBase1intmain(){Derivedclassx(5,6,7,8,9); return0;}335.4多

承01多繼承的概念在現(xiàn)實生活中,很多繼承均表現(xiàn)為多重繼承。一個派生類可以有多個直接基類,則這種繼承方式稱為多繼承,或稱為多重繼承派生類與每一個基類之間關(guān)系可以看作是一個單繼承。多繼承時派生類的聲明class派生類名:繼承方式1基類名1,

繼承方式2基類名2,...{

成員聲明;}注意:每一個“繼承方式”,只用于限制對緊隨其后之基類的繼承。02多繼承構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用次序多繼承的構(gòu)造函數(shù)調(diào)用順序派生類的構(gòu)造函數(shù)須同時負責(zé)該派生類所有基類構(gòu)造函數(shù)的調(diào)用。構(gòu)造函數(shù)調(diào)用順序是:先調(diào)用所有基類的構(gòu)造函數(shù),再調(diào)用派生類的構(gòu)造函數(shù)。處于同一層次的各基類構(gòu)造函數(shù)的調(diào)用順序取決于定義派生類所指定的基類順序,與派生類構(gòu)造函數(shù)中所定義的成員初始化列表順序無關(guān)。多繼承的析構(gòu)函數(shù)的調(diào)用順序執(zhí)行派生類的析構(gòu)函數(shù);按照子對象聲明的相反順序依次調(diào)用子對象的析構(gòu)函數(shù);按照基類聲明的相反順序依次調(diào)用各基類的析構(gòu)函數(shù)03多繼承應(yīng)用舉例【例5-7】多繼承方式下構(gòu)造函數(shù)的調(diào)用順序。#include<iostream>usingnamespacestd;classBase1{public:Base1(inti){a=i;cout<<"constructingBase1a="<<a<<endl;}private:inta; };classBase2{public:Base2(inti){ b=i;cout<<"constructingBase2b="<<b<<endl; }private:intb; };classDerivedclass:publicBase1,publicBase2{public:Derivedclass(inti,intj,intk);private:intc; };Derivedclass::Derivedclass(inti,intj,intc):Base2(i),Base1(j){this->c=c;cout<<"constructingDerivedclassc="<<c<<endl;}intmain(){Derivedclassx(5,6,7); return0;}constructingBase1a=6constructingBase2b=5constructingDerivedclassc=7Pressanykeytocontinue程序運行結(jié)果:04二義性問題在多重繼承中,派生類對基類成員訪問在下列兩種情況下可能出現(xiàn)二義性。訪問不同基類的相同名成員時可能出現(xiàn)二義性訪問共同基類中成員時可能出現(xiàn)二義性多重繼承可以反映現(xiàn)實生活中的情況,能夠有效地處理一些較復(fù)雜的問題,使編寫程序具有靈活性,充分體現(xiàn)了軟件重用的優(yōu)點,但是由于多重繼承方式下,派生類可能有多個直接基類或間接基類,可能造成對基類中某個成員的訪問出現(xiàn)了不確定的情況,使得這種訪問具有二義性。g(),j()f()A類B1類g(),h()B2類D類g(),p()如果聲明:Dc1;調(diào)用哪個函數(shù)時會產(chǎn)生二義性的問題?AB1B2D則c1.f();具有二義性而c1.g();無二義性(同名隱藏)04二義性問題bb1bb2dBase類成員Base類成員Base1類成員Base2類成員Derived類對象各類包含的數(shù)據(jù)成員04二義性問題。二義性問題解決方法(1)成員名限定

通過類的作用域限定符(::)明確限定出現(xiàn)二義性的成員是繼承自哪一個基類。(2)成員重定義

在派生類中新增一個與基類中成員相同的成員,由于同名覆蓋,程序?qū)⒆詣舆x擇派生類新增的成員。一是使用作用域運算符。二是將直接基類的共同基類設(shè)置為虛基類。直接基類名::數(shù)據(jù)成員名直接基類名::成員函數(shù)名(參數(shù)表)04二異性問題【例5-9】派生類覆蓋基類中的同名成員#include<iostream>usingnamespacestd;classBase1{ public:

inti;

voidfun(){cout<<"Base1的fun函數(shù)被調(diào)用"<<endl;}};classBase2{ public:

inti;

voidfun(){cout<<"Base2的fun函數(shù)被調(diào)用"<<endl;}};classDerived:publicBase1,publicBase2{ public:

inti;

voidfun(){cout<<"Derived的fun函數(shù)被調(diào)用"<<endl;}};intmain(){

Derivedd;

Derived*p=&d;

d.i=1;

d.fun();

return0;}同名數(shù)據(jù)成員同名函數(shù)成員程序運行結(jié)果:Derived的fun函數(shù)被調(diào)用應(yīng)用舉例【例】多重繼承派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)#include<iostream>usingnamespacestd;classBase1 {public:

Base1(inti){cout<<"constructingBase1"<<i<<endl;}

~Base1(){cout<<"destructingBase1"<<endl;}};classBase2 {public:Base2(intj){cout<<"constructingBase2"<<j<<endl;}~Base2(){cout<<"destructingBase2"<<endl;} };classBase3{public:Base3(){cout<<"constructingBase3*"<<endl;}~Base3(){cout<<"destructingBase3"<<endl;} };classDerived:publicBase2,publicBase1,publicBase3 {public:Derived(inta,intb,intc,intd):Base1(a),memberA2(d),memberA1(c),Base2(b){}private:Base1memberA1;Base2memberA2;Base3memberA3;};intmain(){Derivedobj(1,2,3,4);return0;}constructingBase22constructingBase11constructingBase3*constructingBase13constructingBase24constructingBase3*destructingBase3destructingBase2destructingBase1destructingBase3destructingBase1destructingBase2應(yīng)用舉例#include<iostream>usingnamespacestd;classB1{protected:intb1,m;public:B1(){b1=3;m=4;}};classB2{protected:intb2,m;public:B2(){b2=5;m=6;}};classD:publicB1,publicB2{intd,m;public:D(){d=7;m=8;}voidshow(){cout<<B1::b1<<"\t"<<b2<<"\t"<<d<<'\n';cout<<B1::m<<"\t"<<B2::m<<"\t"<<m<<'\n';}};intmain(){Dtest;test.show();return0;}3

574

6

8testB1::b1=3B1::m=4B2::b2=5B2::m=6D::d=7D::m=8程序運行結(jié)果5.5虛

類01虛基類的概念基類Aa派生類BA::a派生類CA::a派生類DA::aA::a派生類DA::avirtualvirtual在多重派生的過程中,共同一個基類經(jīng)過多級繼承后會出現(xiàn)用“類名::”無法解決的二義性問題。欲使共同的基類在派生中只有一個拷貝,可將此基類說明成虛基類。虛基類把從不同的路徑繼承過來的虛基類的派生成員在派生類中只出現(xiàn)一次。02虛基類的聲明方法聲明虛基類的方法是,定義派生類時,在基類名稱的前面加上關(guān)鍵字virtual。class派生類名:virtual

派生方式基類名{新增成員列表}或class派生類名:派生方式virtual

基類名{新增成員列表}關(guān)鍵字virtual可以放在派生方式的前面,也可以放在派生方式的后面。需要注意的是在第一級繼承時就要將共同基類設(shè)置為虛基類03虛基類的舉例【例5-14】定義虛基類,使派生類中只有基類的一個拷貝#include<iostream>usingnamespacestd;classBase0{public: intvar0; Base0(inta=0){var0=a;}};classBase1:virtualpublicBase0{public: //新增外部接口

intvar1; Base1(inta,intb):Base0(a){var1=b;}};classBase2:virtualpublicBase0{//定義派生類Base2public: //新增外部接口

intvar2; Base2(inta,intc):Base0(a){var2=c;}};classDerived:publicBase1,publicBase2{public: //新增外部接口

intvar;Derived(inta,intb,intc,intd):Base1(a,b),Base2(a,c) {var=d; }};intmain(){ Derivedd(2,4,6,8); cout<<"var0="<<d.var0<<endl;d.var0=10;cout<<"通過對象在d將var0設(shè)置成"<<d.var0<<endl;cout<<"通過Base2類訪問var0,var0="<<d.Base2::var0<<endl;cout<<"通過Base1類訪問var0,var0="<<d.Base1::var0<<endl;return0;}var0=0通過對象在d將var0設(shè)置成10通過Base2類訪問var0,var0=10通過Base1類訪問var0,var0=10直接訪問var05-5.mp4

(3)類Derived中只有一個虛基類Base0,所以在執(zhí)行類Base1和類Base2的構(gòu)造函數(shù)時都不調(diào)用虛基類的構(gòu)造函數(shù),而是在類Derived中直接調(diào)用虛基類Base0的缺省的構(gòu)造函數(shù):Base0(inta=0){var0=a;},所以var0=0,若將構(gòu)造函數(shù)改為:Base0(inta){x=a;},則編譯時會發(fā)生錯誤。若將類Derived的構(gòu)造函數(shù)改為:(1)改變成員var0值時,由基類Base1和Base2訪問得到的var0值是相同的。(2)由虛基類派生出的派生類,必須在其構(gòu)造函數(shù)的成員初始化列

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論