C++多態(tài)的實現(xiàn)機(jī)制深入理解
在面試過程中C++的多態(tài)實現(xiàn)機(jī)制經(jīng)常會被面試官問道。大家清楚多態(tài)到底該如何實現(xiàn)嗎?下面小編抽空給大家介紹下多態(tài)的實現(xiàn)機(jī)制。
1. 用virtual關(guān)鍵字申明的函數(shù)叫做虛函數(shù),虛函數(shù)肯定是類的成員函數(shù)。
2. 存在虛函數(shù)的類都有一個一維的虛函數(shù)表叫做虛表。類的對象有一個指向虛表開始的虛指針。虛表是和類對應(yīng)的,虛表指針是和對象對應(yīng)的。
3. 多態(tài)性是一個接口多種實現(xiàn),是面向?qū)ο蟮暮诵?。分為類的多態(tài)性和函數(shù)的多態(tài)性。
4. 多態(tài)用虛函數(shù)來實現(xiàn),結(jié)合動態(tài)綁定。
5. 純虛函數(shù)是虛函數(shù)再加上= 0。
6. 抽象類是指包括至少一個純虛函數(shù)的類。
多態(tài)的簡單介紹
一般來說,多態(tài)分為兩種,靜態(tài)多態(tài)和動態(tài)多態(tài)。靜態(tài)多態(tài)也稱編譯時多態(tài),主要包括模板和重載。而動態(tài)多態(tài)則是通過類的繼承和虛函數(shù)來實現(xiàn),當(dāng)基類和子類擁有同名同參同返回的方法,且該方法聲明為虛方法,當(dāng)基類對象,指針,引用指向的是派生類的對象的時候,基類對象,指針,引用在調(diào)用基類的方法,實際上調(diào)用的是派生類方法。這就是動態(tài)多態(tài)。
靜態(tài)多態(tài)的實現(xiàn)
靜態(tài)多態(tài)靠編譯器來實現(xiàn),簡單來說就是編譯器對原來的函數(shù)名進(jìn)行修飾,在c語言中,函數(shù)無法重載,是因為,c編譯器在修飾函數(shù)時,只是簡單的在函數(shù)名前加上下劃線"_" 。而c++編譯器不同,它根據(jù)函數(shù)的類型,個數(shù)來對函數(shù)名進(jìn)行修飾,這就使得函數(shù)可以重載,同理,模板也是可以實現(xiàn)的,針對不同類型的實參來產(chǎn)生對應(yīng)的特化的函數(shù),通過增加修飾,使得不同的類型參數(shù)的函數(shù)得以區(qū)分。
以下段程序為例
#include <iostream> using namespace std; template <typename T1, typename T2> int fun(T1 t1, T2 t2){} int foofun(){} int foofun(int){} int foofun(int , float){} int foofun(int , float ,double){} int main(int argc, char *argv[]) { fun(1, 2); fun(1, 1.1); foofun(); foofun(1); foofun(1, 1.1); foofun(1, 1.1, 1.11); return 0; }
經(jīng)過編譯之后:
只選取main函數(shù)部分來看:
可以發(fā)現(xiàn),調(diào)用的函數(shù)名均發(fā)生了變化,都加了相應(yīng)的修飾,使得調(diào)用的函數(shù)是不一樣的,靜態(tài)多態(tài)就是如此。
動態(tài)多態(tài)的實現(xiàn)
聲明一個類時,如果類中有虛方法,則自動在類中增加一個虛函數(shù)指針,該指針指向的是一個虛函數(shù)表,虛函數(shù)表中存著每個虛函數(shù)真正對應(yīng)的函數(shù)地址。動態(tài)多態(tài)采用一種延遲綁定技術(shù),普通的函數(shù)調(diào)用,在編譯期間就已經(jīng)確定了調(diào)用的函數(shù)的地址,所以無論怎樣調(diào)用,總是那個函數(shù),但是擁有虛函數(shù)的類,在調(diào)用虛函數(shù)時,首先去查虛函數(shù)表,然后在確定調(diào)用的是哪一個函數(shù),所以,調(diào)用的函數(shù)是在運行時才會確定的。
在聲明基類對象時,虛函數(shù)表中綁定的就是基類的方法的地址。在聲明派生類對象時,虛函數(shù)表中綁定的就是派生類的方法。在對象被創(chuàng)建之后(以指針為例),無論是基類指針還是派生類指針指向這個對象,虛函數(shù)表是不會改變的。
以下段程序為例:
#include <iostream> using namespace std; class Base { public: virtual void fun() { cout << "this is base fun" << endl; } }; class Derived : public Base { public: void fun() { cout << "this is Derived fun" << endl; } }; int main(int argc, char *argv[]) { Base b1; Derived d1; Base *pb = &d1; Derived *pd = (Derived *)&b1; b1.fun(); pd->fun(); d1.fun(); pb->fun(); return 0; }
運行結(jié)果如下:
從結(jié)果可以看出,當(dāng)一個對象被創(chuàng)建之后,在調(diào)用虛函數(shù)的時候,無論是派生類指針還是基類指針指向這個對象,調(diào)用虛函數(shù)的結(jié)果是一樣的。因為,虛函數(shù)表是不變。當(dāng)然,有可能在多繼承中會有多個虛函數(shù)表從而導(dǎo)致函數(shù)調(diào)用時調(diào)用不同的虛函數(shù)表,這里不做考慮。
以上所述是小編給大家介紹的C++多態(tài)的實現(xiàn)機(jī)制理解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對我們網(wǎng)站的支持!
上一篇:關(guān)于C++ string和c類型字符數(shù)組的對比
欄 目:C語言
下一篇:C 語言快速排序?qū)嵗a
本文標(biāo)題:C++多態(tài)的實現(xiàn)機(jī)制深入理解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2153.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10c語言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
- 01-10深入二叉樹兩個結(jié)點的最低共同父結(jié)點的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計- 解析最少換車次數(shù)的問題詳解
- 01-10c語言 跳臺階問題的解決方法


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置