多態(tài)是c++中很重要的一環(huán)。多態(tài)可以分為以下幾個層面來剖析:
成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)與策劃設(shè)計,湯旺網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:湯旺等地區(qū)。湯旺做網(wǎng)站價格咨詢:18980820575
1.對象的類型
2.多態(tài)
3.虛表
先說第一點對象的類型,這個非常簡單。比如說、
int a;
那么我就定義了一個int類型的變量a。再來看下面的代碼
class Base { }; class Derive:public Base { };
這里我寫了一個Base類和一個Derive類,并且Derive類是派生于Base類
Base b; Derive d; Base* pb=&b; pb=&d;
上面的代碼實例化了一個Base類類型的對象b,Derive類類型的對象d,Base*類型的指針pb。
pb的靜態(tài)類型就是Base*類型,我們也可以讓pb指向d,Derive*就是pb的動態(tài)類型。
下面來說說第二點,多態(tài)。
int Add(int left,int right) { return left+right; } double Add(double left,double right) { return left+right; }
上面這兩個函數(shù)構(gòu)成了函數(shù)的重載,傳進去int類型的參數(shù)就調(diào)用上面的,double類型的參數(shù)就調(diào)用下面的。這也是一種多態(tài),稱為靜態(tài)的多態(tài)。還有一種泛型編程也是靜態(tài)的多態(tài)。靜態(tài)多態(tài)就是在編譯器編譯期間完成的,編譯器根據(jù)函數(shù)的實參的類型(可能進行隱式的類型轉(zhuǎn)換),可推斷出到底要調(diào)用哪個函數(shù),如果有對應(yīng)的函數(shù)就調(diào)用該函數(shù),否則就會出現(xiàn)編譯錯誤。
那么動態(tài)多態(tài)(也叫動態(tài)綁定)就是指在程序執(zhí)行期間判斷所引用對象的實際類型,根據(jù)其實際類型調(diào)用相應(yīng)的方法。
使用virtual關(guān)鍵字來修飾函數(shù),指明該函數(shù)為虛函數(shù),派生類需要重新實現(xiàn),編譯器將實現(xiàn)動態(tài)綁定。
所謂虛函數(shù)就是指在類中被聲明為virtual的成員,基類希望這種成員在派生類中重定義。除了構(gòu)造函數(shù)外,任意非static成員都可以為虛成員。保留字 virtual 只在類內(nèi)部的成員函數(shù)聲明中出現(xiàn),不能用在類定義體外部出現(xiàn)在函數(shù)定義上。
看一段代碼:
class Base { public: virtual void FunTest() { cout<<"Base::FunTest()"<<endl; } }; class Derive :public Base { public: void FunTest() { cout<<"Derive::FunTest()"<<endl; } }; int main() { Derive d; d.FunTest(); Base b; b.FunTest(); Base *pb=&b; pb->FunTest(); pb=&d; pb->FunTest(); return 0; }
在這一段代碼里面,我定義了兩個類一個是Base,另一個是他的派生類Derive。Base類里面有一個虛函數(shù)FunTest(),Derive類里面也有一個FunTest()。并且在主函數(shù)里面實例化了兩個類的對象,并且調(diào)用了FunTest函數(shù),下面也定義了Base*類型的指針,先指向b,然后調(diào)用了FunTest函數(shù),之后指向d,然后調(diào)用FunTest函數(shù)。這段代碼運行結(jié)果會是什么樣呢?
正如我們所看到的調(diào)用派生類里面的函數(shù)他有他就調(diào)用他自己的,他沒有再去基類里面找。
那么動態(tài)綁定實現(xiàn)的條件是什么呢?第一,必須要是虛函數(shù)。第二,要通過基類類型的引用或者指針調(diào)用。
class CBase { public: virtual void FunTest1(int _iTest) { cout << "CBase::FunTest1()" << endl; } void FunTest2(int _iTest) { cout << "CBase::FunTest2()" << endl; } virtual void FunTest3(int _iTest1) { cout << "CBase::FunTest3()" << endl; } virtual void FunTest4(int _iTest) { cout << "CBase::FunTest4()" << endl; } }; class CDerive:public CBase { public: virtual void FunTest1(int _iTest) { cout << "CDerive::FunTest1()" << endl; } virtual void FunTest2(int _iTest) { cout << "CDerive::FunTest2()" << endl; } void FunTest3(int _iTest1) { cout << "CDerive::FunTest3()" << endl; } virtual void FunTest4(int _iTest1,int _iTest2) { cout << "CDerive::FunTest4()" << endl; } }; int main() { CBase* pBase = new CDerive; pBase->FunTest1(0); pBase->FunTest2(0); pBase->FunTest3(0); pBase->FunTest4(0); return 0; }
上面是一個例子,CBase類是CDerive類的基類。之后FunTest1()是一個虛函數(shù),F(xiàn)unTest2()不是一個虛函數(shù),F(xiàn)unTest3()也是虛函數(shù),F(xiàn)unTest4()雖然是虛函數(shù)但是在子類里面重新實現(xiàn)給了兩個參數(shù)。所以運行結(jié)果是這樣的:
假如我們想調(diào)用CDerive里面的FunTest4(),我們就要用CDerive類的對象了。就像下面這樣:
CDerive d; d.FunTest4(0, 0);
我們這里有一個圖片,能看明白繼承體系中同名成員函數(shù)的關(guān)系:
這里還需要注意:構(gòu)造函數(shù)是不可以定義為虛函數(shù)的,因為構(gòu)造函數(shù)是用來構(gòu)建我們的對象 的,構(gòu)造函數(shù)沒有執(zhí)行完我們的對象就是不完整的。假如我們要調(diào)用構(gòu)造函數(shù),是需要通過我們的基類對象來調(diào)用的,但是我們的對象都沒有構(gòu)造完,所以是不能這樣的。
靜態(tài)函數(shù)和友元函數(shù)也同樣不可以用virtual來修飾。因為這兩種函數(shù)都沒有this指針。
這里還有一個東西:
class test { virtual void Test() = 0; };
這段代碼定義的類叫抽象類。它不能夠?qū)嵗a(chǎn)生對象,它只是提供一些接口。它里面的那個函數(shù)后面跟了一個=0,表示它是純虛函數(shù),它表示它的派生類要對它這個函數(shù)進行重寫。
最后來說虛表和虛指針。
當我們求sizeof(test)時,我們得出的結(jié)果是4。為什么呢?對類求大小的時候不應(yīng)該是它的成員的大小嗎?這里就是有一個虛指針。那這個虛指針指向那里呢?是指向的虛表。虛表里面存的就是虛函數(shù)的地址。
舉一個例子:
class test { public: virtual void FunTest1() {} virtual void FunTest2() {} virtual void FunTest3() {} virtual void FunTest4() {} };
這個類里面只有四個虛函數(shù),那么sizeof(test)等于多少呢?
再來看看t中到底有什么:
所以當我們要調(diào)用虛函數(shù)的時候,編譯器是先找到我們的虛表地址,之后找到對應(yīng)的虛函數(shù)。
網(wǎng)頁標題:c++多態(tài)
網(wǎng)站路徑:http://www.ekvhdxd.cn/article36/jecdpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、定制網(wǎng)站、外貿(mào)建站、云服務(wù)器、網(wǎng)站設(shè)計、標簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)