最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析C++中的虛函數(shù)與多態(tài)

 更新時(shí)間:2013年09月24日 10:00:38   作者:  
對C++ 了解的人都應(yīng)該知道虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)和一個(gè)指向虛函數(shù)表的指針(vptr)來實(shí)現(xiàn)的

1.C++中的虛函數(shù)
C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制。關(guān)于多態(tài),簡而言之就是用父類型別的指針指向其子類的實(shí)例,然后通過父類的指針調(diào)用實(shí)際子類的成員函數(shù)。這種技術(shù)可以讓父類的指針有“多種形態(tài)”,這是一種泛型技術(shù)。所謂泛型技術(shù),說白了就是試圖使用不變的代碼來實(shí)現(xiàn)可變的算法。比如:模板技術(shù),RTTI技術(shù),虛函數(shù)技術(shù),要么是試圖做到在編譯時(shí)決議,要么試圖做到運(yùn)行時(shí)決議。

對C++ 了解的人都應(yīng)該知道虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)和一個(gè)指向虛函數(shù)表的指針(vptr)來實(shí)現(xiàn)的。虛函數(shù)表,簡稱為vtbl,虛函數(shù)表表對實(shí)現(xiàn)多態(tài)起著至關(guān)重要的作用。在這個(gè)表中,主要保存了一個(gè)類中的虛函數(shù)的地址,這張表解決了繼承、覆蓋的問題,保證其內(nèi)容能真實(shí)反應(yīng)實(shí)際的函數(shù)。每一個(gè)包含虛函數(shù)的類的實(shí)例都包含一個(gè)cptr指針,指向虛函數(shù)表的首地址。我們可以通過這個(gè)指針找到要訪問的虛函數(shù)的,完成虛函數(shù)的調(diào)用主要包括:找到虛函數(shù)表的首地址(vptr),通過cptr找到要使用虛函數(shù)地址,調(diào)用虛函數(shù)。那么使用虛函數(shù)大家總要考慮效率的問題,實(shí)際上為了提高效率,C++的編譯器是保證虛函數(shù)表的指針存在于對象實(shí)例中最前面的位置,這是為了保證取到虛函數(shù)表的有最高的性能,這意味著我們通過對象實(shí)例的地址得到這張?zhí)摵瘮?shù)表,然后通過遍歷表就可以找到其中的虛函數(shù)的地址,然后調(diào)用相應(yīng)的函數(shù)。不妨看看下面的代碼:

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void f() { cout << "Base::f" << endl; }
    virtual void g() { cout << "Base::g" << endl; }
    virtual void h() { cout << "Base::h" << endl; }
};

typedef void(*Fun)(void);


int main()
{
    Base b;
    Fun pFun = NULL;
    cout << "虛函數(shù)表地址:" << (int*)(&b) << endl;
    cout << "虛函數(shù)表 — 第一個(gè)函數(shù)地址:" << (int*)*(int*)(&b) << endl;
    pFun = (Fun)*((int*)*(int*)(&b));
    pFun();
    return 0;
}


通過這個(gè)示例,可以看到,通過強(qiáng)行把&b轉(zhuǎn)成int *,取得虛函數(shù)表的地址(vptr),然后,再次取址就可以得到第一個(gè)虛函數(shù)的地址了,也就是Base::f(),這在上面的程序中得到了驗(yàn)證(把int* 強(qiáng)制轉(zhuǎn)成了函數(shù)指針)。通過這個(gè)示例,我們就可以知道如果要調(diào)用Base::g()和Base::h(),其代碼如下:
復(fù)制代碼 代碼如下:

(Fun)*((int*)*(int*)(&b)+0); // Base::f()

(Fun)*((int*)*(int*)(&b)+1); // Base::g()

(Fun)*((int*)*(int*)(&b)+2); // Base::h()


可以看看虛函數(shù)表的圖是怎么畫的:

            

大家都知道,多態(tài)是通過繼承實(shí)現(xiàn)的,那么我們要說說虛函數(shù)繼承的問題。繼承就涉及到了虛函數(shù)的覆蓋了,實(shí)際上不被覆蓋的虛函數(shù)和多態(tài)又有什么聯(lián)系呢?這里我們討論有覆蓋的虛函數(shù)表是什么樣的,假設(shè)存在下面的繼承關(guān)系:

        

看看虛函數(shù)表示什么樣的:

        

可以發(fā)現(xiàn),Base::f()被覆蓋了,這樣若把Derive的實(shí)例賦值給一個(gè)基類Base指針pBase,通過pBase->f();則訪問的是子類中的f()也就是完成了多態(tài)。那么虛函數(shù)表中的內(nèi)容到底是怎么樣的呢?可以看看下面的四句話就會明白!

1.虛函數(shù)按照其聲明順序放于表中。

2.父類的虛函數(shù)在子類的虛函數(shù)前面。

3.覆蓋的f()函數(shù)被放到了虛表中原來父類虛函數(shù)的位置。

4.沒有被覆蓋的函數(shù)依舊。

2.用虛函數(shù)實(shí)現(xiàn)多態(tài)
看看下面的多態(tài)的代碼:

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void Print()
    {
        cout<<"Base::Print()"<<endl;
    }
};
class Derive : public Base
{
public:
    virtual void Print()
    {
        cout<<"Derive::Print()"<<endl;
    }
};
int main()
{
    Derive derive;
    Base *pBase = &derive;
    pBase->Print();
    return 0;
}
//多態(tài)代碼


實(shí)現(xiàn)虛函數(shù)的代碼,一定要切記:一定是基類的指針指向子類的對象的地址。首先試著理解一下用虛函數(shù)實(shí)現(xiàn)多態(tài)的原理,如果實(shí)在沒理解為什么虛函數(shù)能實(shí)現(xiàn)多態(tài),又為什么這樣實(shí)現(xiàn)多態(tài),上網(wǎng)再搜一搜相關(guān)的資料?。?!

相關(guān)文章

  • C++ STL中的常用遍歷算法分享

    C++ STL中的常用遍歷算法分享

    這篇文章主要為大家詳細(xì)介紹了C++ STL中兩個(gè)常用的遍歷算法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)與借鑒價(jià)值,感興趣的小伙伴可以參考一下
    2022-12-12
  • C語言實(shí)現(xiàn)三子棋游戲的示例代碼

    C語言實(shí)現(xiàn)三子棋游戲的示例代碼

    今天我們將會用C語言實(shí)現(xiàn)三子棋。所謂三子棋,就是三行三列的棋盤,玩家可以和電腦下棋,率先連成三個(gè)的獲勝。話不多說,我們開始吧
    2022-10-10
  • C++中正則表達(dá)式的使用方法詳解

    C++中正則表達(dá)式的使用方法詳解

    幾乎所有的編程語言都支持正則表達(dá)式。 C++從C++11開始直接支持正則表達(dá)式。除了編程語言之外,大多數(shù)文本處理程序都使用正則表達(dá)式。本文將探討正則表達(dá)式的一般細(xì)節(jié)以及C++編程方面的細(xì)節(jié),感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • C++中對象的動態(tài)建立與釋放詳解及其作用介紹

    C++中對象的動態(tài)建立與釋放詳解及其作用介紹

    這篇文章主要介紹了C++中對象的動態(tài)建立與釋放詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C語言結(jié)構(gòu)體內(nèi)存的對齊知識詳解

    C語言結(jié)構(gòu)體內(nèi)存的對齊知識詳解

    這篇文章主要介紹了C語言結(jié)構(gòu)體內(nèi)存的對齊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語言實(shí)現(xiàn)運(yùn)籌學(xué)中的馬氏決策算法實(shí)例

    C語言實(shí)現(xiàn)運(yùn)籌學(xué)中的馬氏決策算法實(shí)例

    這篇文章主要介紹了C語言實(shí)現(xiàn)運(yùn)籌學(xué)中的馬氏決策算法,簡單介紹了馬氏決策的概念,并結(jié)合實(shí)例形式分析了C語言實(shí)現(xiàn)馬氏決策算法的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-09-09
  • c++ 數(shù)字類型和字符串類型互轉(zhuǎn)詳解

    c++ 數(shù)字類型和字符串類型互轉(zhuǎn)詳解

    今天小編就為大家分享一篇講解c++ 數(shù)字類型和字符串類型互轉(zhuǎn)的文章,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-09-09
  • C語言數(shù)組學(xué)習(xí)之特殊矩陣的壓縮存儲

    C語言數(shù)組學(xué)習(xí)之特殊矩陣的壓縮存儲

    矩陣在計(jì)算機(jī)圖形學(xué)、工程計(jì)算中都占有舉足輕重的地位,本文將討論如何將矩陣更有效地存儲在內(nèi)存中,并且能夠方便地提取矩陣中的元素。感興趣的同學(xué)可以了解一下
    2021-12-12
  • C++實(shí)現(xiàn)中值濾波的示例代碼

    C++實(shí)現(xiàn)中值濾波的示例代碼

    本文主要介紹了C++實(shí)現(xiàn)中值濾波的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++實(shí)現(xiàn)推箱子小游戲

    C++實(shí)現(xiàn)推箱子小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)推箱子小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01

最新評論

万源市| 台山市| 探索| 柳河县| 昌邑市| 疏附县| 莒南县| 扎囊县| 兰坪| 特克斯县| 南城县| 大田县| 仪陇县| 沈丘县| 华安县| 丽江市| 绩溪县| 宁陵县| 华安县| 高州市| 贺兰县| 宿迁市| 交口县| 凤台县| 天门市| 天气| 宣恩县| 山丹县| 延寿县| 华坪县| 湘潭市| 开封市| 明星| 楚雄市| 富川| 孝昌县| 马尔康县| 尚义县| 万州区| 德令哈市| 临澧县|