計(jì)算機(jī)科學(xué)及編程導(dǎo)論模塊6_第1頁(yè)
計(jì)算機(jī)科學(xué)及編程導(dǎo)論模塊6_第2頁(yè)
計(jì)算機(jī)科學(xué)及編程導(dǎo)論模塊6_第3頁(yè)
計(jì)算機(jī)科學(xué)及編程導(dǎo)論模塊6_第4頁(yè)
計(jì)算機(jī)科學(xué)及編程導(dǎo)論模塊6_第5頁(yè)
已閱讀5頁(yè),還剩80頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

模塊6多態(tài)性計(jì)算機(jī)科學(xué)與編程導(dǎo)論2本章主要內(nèi)容1多態(tài)性的概念2函數(shù)重載3

運(yùn)算符重載4虛函數(shù)3多態(tài)性的概念多態(tài)性是面向?qū)ο蟮闹匾匦?,是指不同?duì)象收到相同的消息時(shí)產(chǎn)生不同的行為。消息是指調(diào)用類的成員函數(shù),不同的行為指不同的實(shí)現(xiàn),即調(diào)用不同的函數(shù)。4多態(tài)性的概念C++支持兩種多態(tài)性:編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性;編譯時(shí)的多態(tài)是在程序編譯過程中確定函數(shù)操作的具體對(duì)象,通過函數(shù)重載來實(shí)現(xiàn);運(yùn)行時(shí)的多態(tài)是在程序運(yùn)行過程中才能確定函數(shù)操作的具體對(duì)象,通過虛函數(shù)來實(shí)現(xiàn)。5多態(tài)的具體實(shí)現(xiàn)在面向?qū)ο笙到y(tǒng)中,將確定操作對(duì)象(確定調(diào)用哪個(gè)函數(shù)實(shí)現(xiàn))的過程稱為聯(lián)編,即把一條消息(調(diào)用類的成員函數(shù))與一個(gè)對(duì)象的方法(具體的函數(shù)版本)相結(jié)合的過程。6多態(tài)的具體實(shí)現(xiàn)聯(lián)編有兩種:靜態(tài)聯(lián)編,在編譯階段確定操作的具體對(duì)象,也稱早期聯(lián)編、早綁定,C語言中所有的函數(shù)調(diào)用都使用早期聯(lián)編;動(dòng)態(tài)聯(lián)編,在系統(tǒng)運(yùn)行過程中確定某一操作對(duì)象,也稱滯后聯(lián)編、晚綁定。main(){execute25}triplelt(){execute38}prNames(){}02538main(){execute34025}triplelt(){execute34038}prNames(){}main(){execute45025}triplelt(){execute45038}prNames(){}編譯執(zhí)行(34000)執(zhí)行(45000)編譯:函數(shù)地址是相對(duì)地址運(yùn)行:函數(shù)地址是絕對(duì)地址靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編?kù)o態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編,都是針對(duì)函數(shù)調(diào)用中的地址而言,而非函數(shù)定義本身靜態(tài)聯(lián)編意味著編譯時(shí)就確定了調(diào)用函數(shù)的相對(duì)地址動(dòng)態(tài)聯(lián)編意味著運(yùn)行時(shí)才能確定調(diào)用函數(shù)的相對(duì)地址92函數(shù)重載靜態(tài)多態(tài)性即編譯時(shí)的多態(tài)是指在編譯階段就決定調(diào)用哪個(gè)同名函數(shù);通過函數(shù)重載來實(shí)現(xiàn)。10構(gòu)造函數(shù)的重載

一個(gè)類可以定義多個(gè)構(gòu)造函數(shù),使用戶選用不同的方式完成對(duì)象數(shù)據(jù)的初始化;重載的所有構(gòu)造函數(shù)同名,但其參數(shù)類型、參數(shù)個(gè)數(shù)必須有所區(qū)別。11例1

構(gòu)造函數(shù)重載。

重載構(gòu)造函數(shù)的例子在類中聲明的多種構(gòu)造函數(shù):classCArea{public:CArea(){x=0;y=0;}//無參數(shù)的構(gòu)造函數(shù)

CArea(intrx,intry=0);//帶缺省參數(shù)的構(gòu)造函數(shù)

CArea(floatrr){rr=0;}//帶一個(gè)參數(shù)的構(gòu)造函數(shù)

CArea(floatrr,char*ra);//帶兩個(gè)參數(shù)的構(gòu)造函數(shù)

};123運(yùn)算符重載運(yùn)算符重載是對(duì)已有的運(yùn)算符賦予多重含義必要性C++中預(yù)定義的運(yùn)算符其運(yùn)算對(duì)象只能是基本數(shù)據(jù)類型,而不適用于用戶自定義類型(如類)實(shí)現(xiàn)機(jī)制將指定的運(yùn)算表達(dá)式轉(zhuǎn)化為對(duì)運(yùn)算符函數(shù)的調(diào)用,運(yùn)算對(duì)象轉(zhuǎn)化為運(yùn)算符函數(shù)的實(shí)參。編譯系統(tǒng)對(duì)重載運(yùn)算符的選擇,遵循函數(shù)重載的選擇原則。13規(guī)則和限制可以重載C++中除下列運(yùn)算符外的所有運(yùn)算符:

.*::?:只能重載C++語言中已有的運(yùn)算符,不可臆造新的。不改變?cè)\(yùn)算符的優(yōu)先級(jí)和結(jié)合性。不能改變操作數(shù)個(gè)數(shù)。經(jīng)重載的運(yùn)算符,其操作數(shù)中至少應(yīng)該有一個(gè)是自定義類型。14兩種形式重載為類成員函數(shù)。重載為友元函數(shù)。15運(yùn)算符函數(shù)聲明形式函數(shù)類型operator運(yùn)算符(形參){......}重載為類成員函數(shù)時(shí)

參數(shù)個(gè)數(shù)=原操作數(shù)個(gè)數(shù)-1 (后置++、--除外)重載為友元函數(shù)時(shí)參數(shù)個(gè)數(shù)=原操作數(shù)個(gè)數(shù),且至少應(yīng)該有一個(gè)自定義類型的形參。16運(yùn)算符成員函數(shù)的設(shè)計(jì)雙目運(yùn)算符B如果要重載B為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達(dá)式oprd1Boprd2,其中

oprd1為A類對(duì)象,則B應(yīng)被重載為A類的成員函數(shù),形參類型應(yīng)該是oprd2

所屬的類型。經(jīng)重載后,表達(dá)式

oprd1Boprd2

相當(dāng)于oprd1.operatorB(oprd2)運(yùn)算符重載17

例2重載運(yùn)算符“+”,實(shí)現(xiàn)兩個(gè)復(fù)數(shù)相加。將“+”運(yùn)算重載為復(fù)數(shù)類的成員函數(shù)。規(guī)則:實(shí)部和虛部分別相加。操作數(shù):兩個(gè)操作數(shù)都是復(fù)數(shù)類的對(duì)象。18#include<iostream.h>classcomplex //復(fù)數(shù)類聲明{public: //外部接口

complex(doubler=0.0,doublei=0.0){real=r;imag=i;//構(gòu)造函數(shù)

complexoperator+(complexc2);//+重載為成員函數(shù)

voiddisplay(); //輸出復(fù)數(shù)

private: //私有數(shù)據(jù)成員

doublereal; //復(fù)數(shù)實(shí)部

doubleimag; //復(fù)數(shù)虛部}; 1819complexcomplex::operator+(complex&c2)//重載函數(shù)實(shí)現(xiàn){ complexc; c.real=c2.real+real; c.imag=c2.imag+imag; returncomplex(c.real,c.imag);}1920voidcomplex::display(){cout<<"("<<real<<","<<imag<<“I”<<“)"<<endl;}intmain()//主函數(shù){ complexc1(3,4),c2(5,-10),c3;//聲明復(fù)數(shù)類的對(duì)象

c3=c1+c2; //使用重載運(yùn)算符完成復(fù)數(shù)加法

cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c1+c2=";c3.display();return0;}2021程序輸出的結(jié)果為:c1=(3,4i)c2=(5,-10i)c1+c2=(8,-6i)2122

重載為類的友元函數(shù)運(yùn)算符重載形式與重載為類的成員函數(shù)相同,只是參數(shù)表中的參數(shù)要求不同;單目運(yùn)算符要求1個(gè)操作數(shù),雙目運(yùn)算符要求2個(gè)操作數(shù),對(duì)同一個(gè)運(yùn)算符,重載為成員函數(shù)總比重載為友元函數(shù)時(shí)少一個(gè)參數(shù)。友元定義重載運(yùn)算符時(shí),所有的操作對(duì)象需要參數(shù)來傳遞。23運(yùn)算符友元函數(shù)的設(shè)計(jì)如果需要重載一個(gè)運(yùn)算符,使之能夠用于操作某類對(duì)象的私有成員,可以此將運(yùn)算符重載為該類的友元函數(shù)。函數(shù)的形參代表依自左至右次序排列的各操作數(shù)。雙目運(yùn)算符B重載后,

表達(dá)式oprd1Boprd2

等同于operatorB(oprd1,oprd2)運(yùn)算符重載24例3采用友元運(yùn)算符函數(shù)實(shí)現(xiàn)復(fù)數(shù)相加。將+(雙目)重載為復(fù)數(shù)類的友元函數(shù)。兩個(gè)操作數(shù)都是復(fù)數(shù)類的對(duì)象。25#include<iostream.h>classcomplex //復(fù)數(shù)類聲明{public: //外部接口

complex(doubler=0.0,doublei=0.0)

{real=r;imag=i;} //構(gòu)造函數(shù)

friendcomplexoperator+(complex&c1,complex&c2);//運(yùn)算符+重載為友元函數(shù)

voiddisplay(); //顯示復(fù)數(shù)的值

private: //私有數(shù)據(jù)成員

doublereal; doubleimag;}; 2526complexoperator+(complex&c1,complex&c2) //運(yùn)算符重載友元函數(shù)實(shí)現(xiàn){ return

complex(c2.real+c1.real,c2.imag+c1.imag);}//其它函數(shù)和主函數(shù)同上例2627“++”和“--”的重載前置“++”和“--”重載為類成員函數(shù)

com.operator++()重載為友元函數(shù)

operator++(Xcom),com是X類的對(duì)象例5:計(jì)數(shù)器中的自加與自減。28“++”和“--”的重載后置“++”和“--”重載為類成員函數(shù)

com.operator++(int)重載為友元函數(shù)

operator++(Xcom,int)com是X類的對(duì)象,int的參數(shù)值為029

賦值運(yùn)算符的重載“=”(賦值)也可以被重載,將賦值號(hào)右邊的對(duì)象數(shù)據(jù)內(nèi)容逐域拷貝到賦值號(hào)左邊的類對(duì)象中;只能重載為成員函數(shù),并且不能被繼承;一般,系統(tǒng)為每個(gè)類都生成一個(gè)缺省的賦值運(yùn)算符,但有些特殊情況下,使用缺省的賦值運(yùn)算符會(huì)出現(xiàn)“指針懸掛問題”,賦值運(yùn)算符重載可以解決。30

賦值運(yùn)算符的重載“&”不必重載,它能返回對(duì)象在內(nèi)存的起始地址。31運(yùn)行時(shí)的多態(tài)性運(yùn)行時(shí)的多態(tài)性是指許多對(duì)象及對(duì)象的操作不能在編譯時(shí)就確定下來,需要在運(yùn)行過程中確定;這種多態(tài)性是用虛函數(shù)來實(shí)現(xiàn)的。324虛函數(shù)在類的聲明中,在函數(shù)原型之前寫virtual。virtual

只用來說明類聲明中的原型,不能用在函數(shù)實(shí)現(xiàn)時(shí)。具有繼承性,基類中聲明了虛函數(shù),派生類中無論是否說明,同原型函數(shù)都自動(dòng)為虛函數(shù)。調(diào)用方式:通過基類指針或引用,執(zhí)行時(shí)會(huì)

根據(jù)指針指向的對(duì)象的類,決定調(diào)用哪個(gè)函數(shù)。4虛函數(shù)虛函數(shù)提供了OOP方法的動(dòng)態(tài)聯(lián)編體系進(jìn)一步學(xué)習(xí)之前,了解“類家族”的概念,記住一個(gè)與虛函數(shù)使用相關(guān)的規(guī)則類家族類家族:同一個(gè)繼承層次結(jié)構(gòu)中的所有相關(guān)的類在一條繼承線上發(fā)展的類家族從一個(gè)父親派生出多個(gè)類的類家族一個(gè)簡(jiǎn)單規(guī)則指向基類的指針可以指向派生類的對(duì)象公有派生36對(duì)象指針對(duì)象指針就是對(duì)象存儲(chǔ)區(qū)的首地址。指向?qū)ο蟮闹羔樣校阂话銓?duì)象的指針;引入派生類后的對(duì)象指針。37

一般對(duì)象的指針定義對(duì)象時(shí)要初始化,初始化后的對(duì)象會(huì)占有一定的內(nèi)存空間,存儲(chǔ)空間的地址就是指向?qū)ο蟮闹羔槨@?Base*p_Base;//聲明對(duì)象指針Baseobj;//定義對(duì)象objp_Base=&obj;//指針p_Base指向?qū)ο髈bj……p_Base->show();//通過對(duì)象指針訪問成員函數(shù)38

引入派生類后的對(duì)象指針引入派生類概念后,任何一個(gè)被說明為指向基類對(duì)象的指針都可以指向它的公有派生類對(duì)象;指向基類對(duì)象的指針,可以指向它的公有派生類的對(duì)象,而不能指向它的私有派生類的對(duì)象。39

引入派生類后的對(duì)象指針

不能將一個(gè)聲明為指向派生類對(duì)象的指針指向其基類的一個(gè)對(duì)象;聲明為指向基類對(duì)象的指針,當(dāng)其指向公有派生類對(duì)象時(shí),只能用它來訪問派生類中從基類繼承來的成員,不能訪問公有派生類中新添的成員。例8計(jì)算和顯示研究生和本科生的學(xué)費(fèi)。40虛函數(shù)的作用在例8中,基類中calfee()和disp()無virtual聲明,則當(dāng)指向基類對(duì)象的指針ptr指向其派生類Graduate對(duì)象時(shí),通過ptr只能訪問Graduate中從基類繼承下來的成員如calfee()和disp(),而不能訪問派生類的calfee()和disp()。41虛函數(shù)的作用給基類calfee()和disp()加上virtual聲明(即虛函數(shù))后,當(dāng)ptr指向其派生類Graduate對(duì)象時(shí),調(diào)用ptr->calfee()和ptr->disp()時(shí)就覆蓋了基類的同名函數(shù),調(diào)用派生類的成員calfee()和disp();虛函數(shù)的定義,使用戶可通過將指向基類對(duì)象的指針指向不同的派生類對(duì)象,來調(diào)用派生類中與基類同名、實(shí)現(xiàn)算法不同的函數(shù),實(shí)現(xiàn)運(yùn)行時(shí)的多態(tài)。42虛函數(shù)的聲明虛函數(shù)的定義在基類中進(jìn)行,即在基類中給想定義為虛函數(shù)的成員函數(shù)聲明前加關(guān)鍵詞virtual

,即:virtual類型說明符函數(shù)名(參數(shù)表)在基類中的某成員函數(shù)被聲明為虛函數(shù)后,此虛函數(shù)可以在一個(gè)或多個(gè)派生類中被重新定義;虛函數(shù)重新定義時(shí),不需要virtual聲明;43虛函數(shù)的聲明在派生類中重新定義虛函數(shù),要求函數(shù)原型包括返回類型、函數(shù)名、參數(shù)個(gè)數(shù)、參數(shù)類型的順序,必須與基類中的原型完全一致,僅函數(shù)實(shí)現(xiàn)不同;可通過成員函數(shù)調(diào)用、指針或引用來訪問虛函數(shù);定義一個(gè)指向基類對(duì)象的指針ptr,并讓它指向同一類族中要調(diào)用此虛函數(shù)的對(duì)象;通過ptr調(diào)用的虛函數(shù)就是ptr指向的對(duì)象的函數(shù)。44例9#include<iostream.h>classB0 //基類B0聲明{public: //外部接口

virtualvoiddisplay()//虛成員函數(shù)

{cout<<"B0::display()"<<endl;}};classB1:publicB0 //公有派生{public:voiddisplay(){cout<<"B1::display()"<<endl;}};classD1:publicB1 //公有派生{public: voiddisplay(){cout<<"D1::display()"<<endl;}};虛函數(shù)voidfun(B0*ptr) //普通函數(shù){ptr->display();}voidmain() //主函數(shù){ B0b0,*p; //聲明基類對(duì)象和指針

B1b1; //聲明派生類對(duì)象

D1d1; //聲明派生類對(duì)象

p=&b0; fun(p); //調(diào)用基類B0函數(shù)成員

p=&b1; fun(p); //調(diào)用派生類B1函數(shù)成員

p=&d1; fun(p); //調(diào)用派生類D1函數(shù)成員}運(yùn)行結(jié)果:B0::display()B1::display()D1::display()4546例10虛函數(shù)的例子47

虛函數(shù)與重載函數(shù)的區(qū)別函數(shù)重載中要求重載函數(shù)的參數(shù)類型、參數(shù)個(gè)數(shù)不同,僅是函數(shù)名相同;虛函數(shù)的重定義,要求函數(shù)名、返回類型、參數(shù)個(gè)數(shù)、參數(shù)類型和順序都與基類中的函數(shù)原型完全一致(特殊的函數(shù)重載)。若不一致,按如下情況處理:

1、函數(shù)參數(shù)相同,僅返回類型不同,作出錯(cuò)處理;

2、函數(shù)參數(shù)有差異,僅函數(shù)名相同,系統(tǒng)會(huì)將它認(rèn)為是一般的函數(shù)重載,將丟失虛特性。48在基類中訪問虛函數(shù),可使用指向基類對(duì)象的指針,也可以使用對(duì)象名直接訪問;派生類中沒重新定義虛函數(shù)時(shí),該類的對(duì)象將使用基類中的虛函數(shù)代碼(繼承下來的);虛函數(shù)必須是一個(gè)類的成員函數(shù);構(gòu)造函數(shù)不能被聲明為virtual,但析構(gòu)函數(shù)可以被聲明為virtual。

虛函數(shù)使用注意:

虛析構(gòu)函數(shù)如果派生類層次中包含析構(gòu)函數(shù),那么把基類的析構(gòu)函數(shù)定義為虛函數(shù)若基類的析構(gòu)函數(shù)聲明為虛函數(shù),則由該基類派生的所有派生類的析構(gòu)函數(shù)也都自動(dòng)成為虛函數(shù),即使派生類的析構(gòu)函數(shù)與基類的析構(gòu)函數(shù)不同名虛析構(gòu)函數(shù)的作用保證使用操作符delete時(shí)能夠調(diào)用正確的析構(gòu)函數(shù)虛析構(gòu)函數(shù)的例子不聲明虛析構(gòu)函數(shù)的結(jié)果虛函數(shù)使用注意在同一個(gè)類家族中,希望一個(gè)指針能指向不同的類,那么把它定義為指向基類定義了指向類家族中對(duì)象的指針,且不同類中有同名函數(shù)時(shí),使用虛函數(shù)定義基類的析構(gòu)函數(shù)為虛函數(shù),可以保證派生類被正確析構(gòu)虛函數(shù)使用注意(續(xù))成員函數(shù)才能聲明為虛函數(shù)構(gòu)造函數(shù)不能是虛函數(shù)內(nèi)聯(lián)函數(shù)不能是虛函數(shù)類家族的存在對(duì)象尚未建立內(nèi)聯(lián)是代碼展開,不是地址54如果基類只表達(dá)一些抽象的概念,而不和具體的事物相聯(lián)系,就不在此基類中定義函數(shù)。但希望基類必須為它的派生類提供一個(gè)公共的界面,可以通過在基類中加入純虛函數(shù)(pruevirtualfunction)來實(shí)現(xiàn)。純虛函數(shù)55純虛函數(shù)是一個(gè)在基類中說明的虛函數(shù),它在該基類中沒有定義,但要求任何派生類都必須定義自己的虛函數(shù)版本。純虛函數(shù)定義形式:

virtualtype

函數(shù)名(參數(shù)表)

=0;“=0”只表示該成員函數(shù)是純虛的。純虛函數(shù)56例如:#include<iostream.h>classshape//定義基類{public:

virtualfloatarea()=0;

//定義純虛函數(shù)

virtualvoidDisp()=0;

//定義純虛函數(shù)};classrectangles:publicshape//定義圖形的派生類矩形類{public:

floatarea();//可以定義

voidDisp();

//可以定義};57

純虛函數(shù)使用注意:純虛函數(shù)只有函數(shù)的名字,不具備函數(shù)功能,不能被調(diào)用。只有在派生類中定義以后,它才有函數(shù)的功能,才可以調(diào)用;純虛函數(shù)的作用只是在基類中保留一個(gè)函數(shù)的名字,以便派生類中定義它的版本;如果基類中沒有保留名字,無法實(shí)現(xiàn)多態(tài)性;如果在派生類中沒有定義純虛函數(shù)的版本,則該虛函數(shù)在派生類中仍然是純虛函數(shù)。58抽象類作用抽象類為抽象和設(shè)計(jì)的目的而聲明,將有關(guān)的數(shù)據(jù)和行為組織在一個(gè)繼承層次結(jié)構(gòu)中,保證派生類具有要求的行為。對(duì)于暫時(shí)無法實(shí)現(xiàn)的函數(shù),可以聲明為純虛函數(shù),留給派生類去實(shí)現(xiàn)。注意抽象類只能作為基類來使用。不能聲明抽象類的對(duì)象。59例11抽象類的例子#include<iostream.h>classB0//抽象基類B0聲明{public://外部接口

virtualvoiddisplay()=0;//純虛函數(shù)成員};classB1:publicB0//公有派生{public: voiddisplay(){cout<<"B1::display()"<<endl;}//虛成員函數(shù)};classD1:publicB1//公有派生{public: voiddisplay(){cout<<"D1::display()"<<endl;}//虛成員函數(shù)};voidfun(B0*ptr) //普通函數(shù){ ptr->display();}voidmain() //主函數(shù){ B0*p; //聲明抽象基類指針

B1b1; //聲明派生類對(duì)象

D1d1; //聲明派生類對(duì)象

p=&b1; fun(p); //調(diào)用派生類B1函數(shù)成員

p=&d1; fun(p); //調(diào)用派生類D1函數(shù)成員}運(yùn)行結(jié)果:B1::display()D1::display()60編寫一個(gè)程序,計(jì)算正方體和球體的表面積和體積重載、覆蓋與隱藏重載成員函數(shù)被重載的特征:相同的范圍(在同一個(gè)類中)函數(shù)名字相同參數(shù)不同與virtual無關(guān)把重載函數(shù)的本名和參數(shù)的數(shù)據(jù)結(jié)合起來,創(chuàng)造函數(shù)的新名字例如有如下兩個(gè)函數(shù)原型intmyAns(floatx,int

j);intmyAns(inti,char

c);用如下語句調(diào)用ans1=myAns(14.2,25);ans2=myAns(62,’x’);intmyAnsFLAOTINT(flaot

x,int

i);int

myAnsINTCHAR(int

i,

char

c);ans1=myAnsFLAOTINT(14,2,25);ans2=myAnsINTCHAR(62,’x’);classCube{public:Cube(){height=1;width=1;length=1;}Cube(int

h,intw,intl);{height=h;width=w;length=l;}

private:

int

height;

intwidth;

intlength;};voidmain(){Cubecube1;Cubecube2(4,5,6);}Cube()CubeIntIntInt(4,5,6)覆蓋覆蓋是指派生類函數(shù)覆蓋基類函數(shù),特征是:不同的范圍(分別位于派生類與基類)函數(shù)名字相同參數(shù)相同基類函數(shù)必須有virtual關(guān)鍵字覆蓋規(guī)則其實(shí)就是C++虛函數(shù)表的實(shí)現(xiàn)原理虛函數(shù)表一個(gè)虛擬函數(shù)地址表,稱為vtable。每個(gè)類的vtable中記錄的是所有聲明為virtual的成員函數(shù)的地址如果在派生類中沒有覆蓋基類的成員函數(shù),則在vtable中記錄的是基類成員函數(shù)的地址如果在派生類中有覆蓋到基類的成員函數(shù),則在vtable中記錄的是派生類成員函數(shù)的地址classbase{

public:

func();

virtualvfunc1();

virtualvfunc2();

virtualvfunc3();

private:

int_data1;

int_data2;

};

classderived:publicbase{

public:vfunc2();};void

main()

{

Derivedd;

Base*pb=&d;

pb->vfunc2();

}

base對(duì)象實(shí)例

vtable

--------------------------------------------------------------------------

vptr--------->(*vfunc1)()----------->base::vfunc1();

_data1

(*vfunc2)()----------->base::vfunc2();

_data2

(*vfunc3)()----------->base::vfunc3();

--------------------------------------------------------------------------derived對(duì)象實(shí)例

vtable

--------------------------------------------------------------------------

vptr

--------->(*vfunc1)()----------->base::vfunc1()

_data1;

(*vfunc2)()----------->derived::vfunc2()

_data2;

(*vfunc3)()----------->base::vfunc3()

--------------------------------------------------------------------------

如果基類中有虛函數(shù),編譯器會(huì)自動(dòng)為每個(gè)由該基類及其派生類所定義的對(duì)象加上一個(gè)叫v-pointer的指針,簡(jiǎn)稱vptr。編譯器還為每個(gè)類加上了一個(gè)叫做vtable的表vptr指向vtable開頭的地方

A對(duì)象實(shí)例

vtable

-----------------------------------------------

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論