青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 195,  comments - 30,  trackbacks - 0

http://hi.baidu.com/walkman0000/blog/item/87b316ce24edd53eb600c8fa.html
我們先看一個例子:
1- 1

#include <iostream.h>

class animal

{

public:

       void sleep()

       {

              cout<<"animal sleep"<<endl;

       }

       void breathe()

       {

              cout<<"animal breathe"<<endl;

       }

};

class fish:public animal

{

public:

       void breathe()

       {

              cout<<"fish bubble"<<endl;

       }

};

void main()

{

       fish fh;

       animal *pAn=&fh;

       pAn->breathe();

}

       注意,在例1-1的程序中沒有定義虛函數。考慮下例1-1的程序執行的結果是什么?

       答案是輸出:animal breathe

       我們在main()函數中首先定義了一個fish類的對象fh,接著定義了一個指向animal類的指針變量pAn,將fh的地址賦給了指針變量pAn,然后利用該變量調用pAn->breathe()。許多學員往往將這種情況和C++的多態性搞混淆,認為fh實際上是fish類的對象,應該是調用fish類的breathe(),輸出“fish bubble”,然后結果卻不是這樣。下面我們從兩個方面來講述原因。

1、 編譯的角度

C++編譯器在編譯的時候,要確定每個對象調用的函數的地址,這稱為早期綁定(early binding),當我們將fish類的對象fh的地址賦給pAn時,C++編譯器進行了類型轉換,此時C++編譯器認為變量pAn保存的就是animal對象的地址。當在main()函數中執行pAn->breathe()時,調用的當然就是animal對象的breathe函數。

2、 內存模型的角度

我們給出了fish對象內存模型,如下圖所示:

 

 

1- 1 fish類對象的內存模型

 

我們構造fish類的對象時,首先要調用animal類的構造函數去構造animal類的對象,然后才調用fish類的構造函數完成自身部分的構造,從而拼接出一個完整的fish對象。當我們將fish類的對象轉換為animal類型時,該對象就被認為是原對象整個內存模型的上半部分,也就是圖1-1中的“animal的對象所占內存”。那么當我們利用類型轉換后的對象指針去調用它的方法時,當然也就是調用它所在的內存中的方法。因此,輸出animal breathe,也就順理成章了。

正如很多學員所想,在例1-1的程序中,我們知道pAn實際指向的是fish類的對象,我們希望輸出的結果是魚的呼吸方法,即調用fish類的breathe方法。這個時候,就該輪到虛函數登場了。

前面輸出的結果是因為編譯器在編譯的時候,就已經確定了對象調用的函數的地址,要解決這個問題就要使用遲綁定(late binding)技術。當編譯器使用遲綁定時,就會在運行時再去確定對象的類型以及正確的調用函數。而要讓編譯器采用遲綁定,就要在基類中聲明函數時使用virtual關鍵字(注意,這是必須的,很多學員就是因為沒有使用虛函數而寫出很多錯誤的例子),這樣的函數我們稱為虛函數。一旦某個函數在基類中聲明為virtual,那么在所有的派生類中該函數都是virtual,而不需要再顯式地聲明為virtual

下面修改例1-1的代碼,將animal類中的breathe()函數聲明為virtual,如下:

1- 2

#include <iostream.h>

class animal

{

public:

       void sleep()

       {

              cout<<"animal sleep"<<endl;

       }

       virtual void breathe()

       {

              cout<<"animal breathe"<<endl;

       }

};

class fish:public animal

{

public:

       void breathe()

       {

              cout<<"fish bubble"<<endl;

       }

};

void main()

{

       fish fh;

       animal *pAn=&fh;

       pAn->breathe();

}

大家可以再次運行這個程序,你會發現結果是“fish bubble”,也就是根據對象的類型調用了正確的函數。

那么當我們將breathe()聲明為virtual時,在背后發生了什么呢?

編譯器在編譯的時候,發現animal類中有虛函數,此時編譯器會為每個包含虛函數的類創建一個虛表(即vtable),該表是一個一維數組,在這個數組中存放每個虛函數的地址。對于例1-2的程序,animalfish類都包含了一個虛函數breathe(),因此編譯器會為這兩個類都建立一個虛表,如下圖所示:

1- 2 animal類和fish類的虛表

       那么如何定位虛表呢?編譯器另外還為每個類的對象提供了一個虛表指針(即vptr),這個指針指向了對象所屬類的虛表。在程序運行時,根據對象的類型去初始化vptr,從而讓vptr正確的指向所屬類的虛表,從而在調用虛函數時,就能夠找到正確的函數。對于例1-2的程序,由于pAn實際指向的對象類型是fish,因此vptr指向的fish類的vtable,當調用pAn->breathe()時,根據虛表中的函數地址找到的就是fish類的breathe()函數。

正是由于每個對象調用的虛函數都是通過虛表指針來索引的,也就決定了虛表指針的正確初始化是非常重要的。換句話說,在虛表指針沒有正確初始化之前,我們不能夠去調用虛函數。那么虛表指針在什么時候,或者說在什么地方初始化呢?

答案是在構造函數中進行虛表的創建和虛表指針的初始化。還記得構造函數的調用順序嗎,在構造子類對象時,要先調用父類的構造函數,此時編譯器只“看到了”父類,并不知道后面是否后還有繼承者,它初始化父類對象的虛表指針,該虛表指針指向父類的虛表。當執行子類的構造函數時,子類對象的虛表指針被初始化,指向自身的虛表。對于例2-2的程序來說,當fish類的fh對象構造完畢后,其內部的虛表指針也就被初始化為指向fish類的虛表。在類型轉換后,調用pAn->breathe(),由于pAn實際指向的是fish類的對象,該對象內部的虛表指針指向的是fish類的虛表,因此最終調用的是fish類的breathe()函數。

要注意:對于虛函數調用來說,每一個對象內部都有一個虛表指針,該虛表指針被初始化為本類的虛表。所以在程序中,不管你的對象類型如何轉換,但該對象內部的虛表指針是固定的,所以呢,才能實現動態的對象函數調用,這就是C++多態性實現的原理。

總結(基類有虛函數):

1、 每一個類都有虛表。

2、 虛表可以繼承,如果子類沒有重寫虛函數,那么子類虛表中仍然會有該函數的地址,只不過這個地址指向的是基類的虛函數實現。如果基類3虛函數,那么基類的虛表中就有三項(虛函數地址),派生類也會有虛表,至少有三項,如果重寫了相應的虛函數,那么虛表中的地址就會改變,指向自身的虛函數實現。如果派生類有自己的虛函數,那么虛表中就會添加該項。

3、 派生類的虛表中虛函數地址的排列順序和基類的虛表中虛函數地址排列順序相同。

posted on 2011-04-08 22:23 luis 閱讀(190) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2012年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

文章分類

文章檔案

友情鏈接

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大胆成人| 亚洲人成啪啪网站| 欧美视频一二三区| 欧美成人69av| 91久久极品少妇xxxxⅹ软件| 韩国av一区二区三区| 一区二区在线视频播放| 一区二区三区自拍| 亚洲精品之草原avav久久| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲电影免费在线观看| 久久综合国产精品| 久久精品一二三区| 亚洲欧美一区二区原创| 亚洲欧美在线免费| 小黄鸭精品密入口导航| 久久久999| 欧美日本乱大交xxxxx| 欧美激情精品久久久久久大尺度| 欧美日韩视频第一区| 国产美女扒开尿口久久久| 激情久久中文字幕| 一本大道久久a久久精二百| 亚洲国产精品悠悠久久琪琪| 性色av一区二区三区在线观看| 久久精品91久久久久久再现| 欧美精品乱码久久久久久按摩| 欧美先锋影音| 亚洲第一色在线| 午夜精品一区二区三区电影天堂 | 欧美激情一区二区三区不卡| 亚洲视频国产视频| 久久香蕉精品| 国产女主播一区二区| 亚洲欧洲日产国码二区| 久久久精品网| 亚洲制服av| 欧美视频不卡中文| 亚洲卡通欧美制服中文| 裸体丰满少妇做受久久99精品 | 免费成人av| 亚洲午夜久久久久久久久电影院 | 亚洲在线国产日韩欧美| 欧美人在线视频| 亚洲黄色天堂| 美女诱惑一区| 久久精品女人| 国产一区欧美日韩| 亚洲国内精品在线| 欧美一区二区三区在线| 日韩亚洲不卡在线| 欧美日韩成人综合| 99国产精品国产精品毛片| 亚洲第一精品福利| 另类国产ts人妖高潮视频| 激情综合五月天| 美女网站在线免费欧美精品| 久久久久成人精品免费播放动漫| 国产在线精品成人一区二区三区 | 久久精品视频在线| 欧美亚洲一区二区三区| 国产亚洲精品久久久久婷婷瑜伽| 香蕉尹人综合在线观看| 亚洲欧美另类综合偷拍| 国产精品资源在线观看| 久久精品视频在线| 久久一区二区三区四区五区| 在线观看日韩av电影| 免费在线观看一区二区| 久久亚洲图片| 日韩视频免费看| 一本大道久久a久久精品综合| 国产精品久久午夜| 久久久久高清| 开元免费观看欧美电视剧网站| 亚洲动漫精品| 亚洲美女网站| 国产精品伦一区| 久久精品视频在线播放| 麻豆精品视频在线观看视频| 夜夜嗨一区二区| 99国产精品久久久久久久久久| 牛人盗摄一区二区三区视频| 99国产精品久久久久久久| 99精品免费| 好看的亚洲午夜视频在线| 欧美成年人网| 欧美午夜不卡影院在线观看完整版免费 | 亚洲国产欧美不卡在线观看| 亚洲精品一品区二品区三品区| 国产精品播放| 在线观看日产精品| 亚洲六月丁香色婷婷综合久久| 欧美婷婷久久| 欧美a级片网| 欧美色欧美亚洲高清在线视频| 欧美一区二区精美| 免费在线观看一区二区| 亚洲女ⅴideoshd黑人| 狼狼综合久久久久综合网| 亚洲在线成人精品| 美女999久久久精品视频| 香蕉久久国产| 欧美日韩精品免费观看视一区二区| 欧美一区二区大片| 欧美日韩a区| 欧美freesex交免费视频| 国产精品乱码人人做人人爱| 亚洲福利视频一区二区| 国产日韩精品综合网站| 亚洲卡通欧美制服中文| 精品成人久久| 国产精品国产馆在线真实露脸| 国产精品日韩欧美大师| 91久久国产综合久久| 国内一区二区在线视频观看| 99精品99| 艳妇臀荡乳欲伦亚洲一区| 久久久久久免费| 欧美中文字幕| 国产精品日韩欧美一区| 亚洲最黄网站| 国产精品99久久久久久久久久久久 | 一区二区三区四区五区精品| 亚洲欧洲美洲综合色网| 久久久久久久综合| 久久免费观看视频| 国产资源精品在线观看| 欧美一区影院| 久久精品一二三| 国产日韩视频| 欧美亚洲一区二区三区| 久久久国产精品一区二区三区| 国产欧美日韩综合精品二区| 一区二区三区四区五区精品视频 | 日韩一区二区免费看| 鲁大师成人一区二区三区| 久久婷婷国产综合尤物精品| 国产午夜精品在线观看| 欧美一区二区三区视频| 欧美在线观看视频一区二区三区| 国产精品成人观看视频国产奇米| 艳女tv在线观看国产一区| 亚洲自拍偷拍视频| 国产精品亚洲综合天堂夜夜 | 久久久视频精品| 国产亚洲成精品久久| 亚洲欧美在线磁力| 久久综合99re88久久爱| 亚洲国产精品成人精品| 免费观看日韩| 久久久久久国产精品一区| 国产私拍一区| 午夜日韩福利| 一个色综合av| 国产精品你懂的| 亚洲女同精品视频| 久久久久欧美精品| 亚洲电影自拍| 欧美日韩一区二区精品| 在线亚洲美日韩| 久久久国产91| 亚洲福利国产精品| 欧美精品一区在线播放| 一本在线高清不卡dvd| 久久精品99国产精品酒店日本| 激情久久影院| 国产精品成人一区二区艾草| 久久九九全国免费精品观看| 亚洲精品123区| 欧美在线二区| 一本色道久久综合亚洲二区三区 | 国内外成人免费激情在线视频| 免费国产自线拍一欧美视频| 在线视频中文亚洲| 久久精品综合| 久久综合综合久久综合| 亚洲午夜日本在线观看| 一区二区三区四区国产精品| 久久综合九色99| 欧美一区二区大片| 亚洲伦理中文字幕| 欧美激情久久久久久| 亚洲国产精品va在看黑人| 噜噜噜91成人网| 美日韩丰满少妇在线观看| 亚洲激情精品| 日韩一级黄色片| 国产综合色在线| 欧美a级大片| 国产精品人成在线观看免费| 一区二区三区国产精华| 亚洲精品国产精品乱码不99| 国产精品网曝门| 亚洲一区二区三区精品在线观看| 国产精品久久综合| 欧美一区免费视频| 欧美在线免费观看亚洲| 午夜精品福利在线观看| 亚欧成人在线|