999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C++語言中的虛函數(shù)研究

2010-04-12 00:00:00徐啟豐萬玉成
現(xiàn)代電子技術 2010年4期

摘 要:虛函數(shù)是面向?qū)ο蟮腃++語言中的一個非常重要的概念。它充分體現(xiàn)了面向?qū)ο笏枷胫械睦^承和多態(tài)性這兩大特性,動態(tài)綁定是C++中實現(xiàn)多態(tài)的一個重要途徑,虛函數(shù)是動態(tài)綁定的基礎。通過深入分析VC++編譯器實現(xiàn)虛函數(shù)的匯編代碼。給出在繼承下的實現(xiàn)模型,并結合實例,在匯編語言層次研究了多態(tài)性的實現(xiàn)機理,揭示了虛函數(shù)和動態(tài)綁定的本質(zhì)。

關鍵詞:虛函數(shù);多態(tài)性;綁定;構造函數(shù)

中圖分類號:TP312文獻標識碼:A

文章編號:1004-373X(2010)04-154-03

Study of Virtual Function in C++

XU Qifeng,HU Yong,WANG Yucheng

(Xuzhou Air Force College,Xuzhou,221000,China)

Abstract:Virtual Function is an important concept of object oriented language C++.It presents the Inheritance and Polymorphism of the idea in object oriented language,dynamic binding is an important approach to realize polymorphism in C++ and virtual function is its foundation,this paper investigates the realization mechanism of virtual function in assemble language in VC++.According to inheritance relationship,the realize model of polymorphism is studied by example and in assemble language,and reveals the essence of virtual function and dynamic binding .

Keywords:virtual function;polymorphism;bind;constructor

0 引 言

多態(tài)性是面向?qū)ο蟪绦蛟O計語言繼數(shù)據(jù)抽象和繼承之后的第三個基本特征[1,2],在C++語言中,多態(tài)性是用虛函數(shù)來實現(xiàn)的[3,4],如果某類中的一個成員函數(shù)被說明為虛函數(shù),該類被稱為多態(tài)類,這就意味著該成員函數(shù)在派生類中可以有不同的實現(xiàn),當用一個基類指針或引用指向一個繼承類對象調(diào)用虛函數(shù)的時候,實際調(diào)用的是繼承類版本的虛函數(shù)。

綁定是指把函數(shù)定義體與函數(shù)調(diào)用相聯(lián)接的過程,按照綁定所進行的階段不同,可分為兩種不同的綁定方法:靜態(tài)綁定和動態(tài)綁定[5,6],靜態(tài)綁定是傳統(tǒng)的過程式程序設計語言所使用的方法,即函數(shù)定義體和函數(shù)調(diào)用間的聯(lián)接發(fā)生在編譯連接階段,這種聯(lián)編又稱早期綁定,因為綁定過程是在程序開始運行之前完成的。靜態(tài)綁定的優(yōu)點是有效性,即速度快,所需內(nèi)存小,易實現(xiàn)代碼優(yōu)化,主要缺點是缺乏靈活性。與靜態(tài)綁定相對應的是動態(tài)綁定,動態(tài)綁定意味著函數(shù)調(diào)用與函數(shù)定義體的聯(lián)接是在程序運行是進行的,即在編譯時,編譯器不能確定某一對象實體與具體那個函數(shù)調(diào)用相聯(lián)接,必須在運行時刻根據(jù)上下文關系來確定[7]。動態(tài)綁定也叫晚期綁定,動態(tài)綁定以效率性來換取靈活性。在C++語言中,當使用基類指針或引用調(diào)用虛函數(shù)采用的就是動態(tài)綁定的方式[8],即根據(jù)基類指針或引用的動態(tài)類型(指針或引用所指向或引用對象的類型)選擇相應的虛函數(shù)版本,而不是根據(jù)基類指針或引用的靜態(tài)類型(聲明指針或引用時所使用的類型)來選擇函數(shù)版本,從而給程序帶來了多態(tài)性[9-11]。

1 虛函數(shù)的實現(xiàn)機理

下面從一個具體的程序來分析虛函數(shù)的實現(xiàn)機理,程序如下,在Visual C++ 6.0編譯器下運行。

#include

using namespace std;

class CBase

{

public:

int Base_x;

virtual void vFun1();

virtual void vFun2();

void Fun3();

};

void CBase::vFun1()

{

cout << \"CBase::vFun1()\"<

}

void CBase::vFun2()

{

cout << \"CBase::vFun2()\"<

}

void CBase::Fun3()

{

cout << \"CBase::Fun3()\"<

}

class CDerived:public CBase

{

int Derived_x;

int Derived_y;

void vFun2();

};

void CDerived::vFun2()

{

cout << \"CDerived::vFun2()\"<

}

void main()

{

CBase * pBase;

CDerived Derived;

pBase = Derived;

pBase->vFun1();

pBase->vFun2();

pBase->Fun3();

}

該程序定義了兩個類:CBase 類和他的派生類CDerived類。CBase類中有兩個虛函數(shù) vFun1()和vFun2(),另外還有一個非虛函數(shù)Fun3(),在CDerived類中改寫了vFun2()的定義,最后,在main()函數(shù)中,用基類Cbase定義了一個指針pBase,然后將定義好的Cderived類的一個對象的地址賦給pBase,即指針pBase的靜態(tài)類型是Cbase,動態(tài)類型是Cderived,接下來用pBase對vFun1(),vFun2(),F(xiàn)un3()分別進行調(diào)用,輸出結果如下:

CBase::vFun1()

CDerived::vFun2()

CBase::Fun3()

下面通過分析編譯器生成的匯編代碼來分析虛函數(shù)的實現(xiàn)機理,首先分析對Fun3()函數(shù)調(diào)用生成的匯編代碼:

pBase->Fun3();

這條語句對應的匯編代碼如下:

mov ecx,DWORD PTR _pBaseMYM[ebp]

call ?Fun3@CBase@@QAEXXZ; CBase::Fun3

從上面的代碼可以看出,因為Fun3()是非虛擬的成員函數(shù),不論pBase 指針所指向?qū)ο蟮念愋褪鞘裁矗瑢un3()的調(diào)用是依據(jù)pBase的靜態(tài)類型Cbase 來綁定相應的函數(shù)定義體的,所以pBase->Fun3()最終轉化成對CBase::Fun3()的調(diào)用。這就是前面所提到的靜態(tài)綁定。下面在看看編譯器為pBase->vFun2()這條語句所生成的匯編代碼:

mov eax,DWORD PTR _pBaseMYM[ebp]

mov edx,DWORD PTR [eax]

mov esi,esp

mov ecx,DWORD PTR _pBaseMYM[ebp]

call DWORD PTR [edx+4]

cmp esi,esp

call __chkesp

_pBaseMYM[ebp]就是pBase的實際值,即Derived對象的地址。對vFun2()的調(diào)用最終轉化為call DWORD PTR [edx+4],從代碼可以看出,edx的值就是Derived對象的地址。為了弄清楚[edx+4]代表什么,需要分析Derived對象的內(nèi)存空間的布局情況,首先看一下Derived對象的構造函數(shù)的代碼,下面摘錄了其中的關鍵代碼:

mov DWORD PTR _thisMYM[ebp],ecx

mov ecx,DWORD PTR _thisMYM[ebp]

call ??0CBase@@QAE@XZ ; CBase::CBase

mov eax,DWORD PTR _thisMYM[ebp]

mov DWORD PTR [eax],OFFSET FLAT:??_7CDerived@@6B@ ; CDerived::′vftable′

mov eax,DWORD PTR _thisMYM[ebp]

Cbase類的構造函數(shù)相關代碼如下所示:

mov DWORD PTR _thisMYM[ebp],ecx

mov eax,DWORD PTR _thisMYM[ebp]

mov DWORD PTR [eax],OFFSET FLAT:??_7CBase@@6B@ ; CBase::′vftable′

mov eax,DWORD PTR _thisMYM[ebp]

從上面的代碼可以看出,編譯器生成的vftable地址即vptr插入到存放對象內(nèi)存區(qū)的首地址(即this指針指向的地方)的代碼。所以說,帶有虛函數(shù)的對象在構造時,涉及到vftable,而vftable在CONST區(qū)定義,代碼如下所示:

CONST SEGMENT

??_7CDerived@@6B@

DDFLAT:?vFun1@CBase@@UAEXXZ; CDerived::′vftable′

DDFLAT:?vFun2@CDerived@@EAEXXZ

CONST ENDS

2 結 語

從上面的代碼可以看出,vftable其實就是一個容納虛函數(shù)的地址的表格[12],Cderived的虛函數(shù)表格里面有從基類繼承而來的虛函數(shù)vFun1()和改寫了定義的vFun2()的地址。Cderived的構造函數(shù)調(diào)用了基類Cbase的構造函數(shù),CBase的構造函數(shù)也有初始化虛函數(shù)指針的過程,但由于Cderived的構造函數(shù)初始化虛函數(shù)指針在調(diào)用CBase的構造函數(shù)之后,因此最終的虛函數(shù)表容納的是派生類的虛函數(shù)的地址,結合前面編譯器為pBase->vFun2()語句所生成的匯編代碼,可以得出如下結論:

(1) 編譯器必須為多態(tài)類的每個對象增加一個vptr指針,由多態(tài)類的構造函數(shù)負責vptr的初始化;

(2) 每個多態(tài)類至少增加一個vftable表到程序的數(shù)據(jù)區(qū),vftable就是一張指向虛擬函數(shù)的函數(shù)指針表;

(3) 每個虛函數(shù)的調(diào)用被編譯器轉化通過查找vftable來定位函數(shù)地址(需要額外的機器指令),如pBase->vFun2()將會轉化為(*pBase->vptr[2])(pBase)。

以上結論是針對visual C++ 6.0編譯器而言的,對于其他編譯器,具體實現(xiàn)雖不完全相同,但都大同小異。如gnu C++編譯器就把指向vtable的指針放在對象尾部而不是頭部。

參考文獻

[1]藍雯飛.C++語言中的面向?qū)ο筇卣魈接慬J].計算機工程與應用,2000,36(9):91-92.

[2]夏承遺,董玉濤,趙德新,等.C++中虛函數(shù)的實現(xiàn)機制[J].天津理工學院學報,2004,20(3):65-67.

[3]Bjarne Stroustrup.The C++ Programming Language[M].Special Edition(影印版).北京:高等教育出版社,2001.

[4]張昀.C++中的多態(tài)性研究[J].教育技術導刊,2009,18(2):65-66.

[5]Terrence W Pratt.程序設計語言:設計與實現(xiàn)[M].傅育熙,譯.北京:電子工業(yè)出版社,2001.

[6]趙紅超,方金云,唐志敏.C++的動態(tài)多態(tài)和靜態(tài)多態(tài)[J].計算機工程,2005,31(20):72-73,87.

[7]Bjarne Stroustrup.C++的設計與演化[M].裘宗燕,譯.北京:機械工業(yè)出版社,2002.

[8]藍雯飛,陸際光.C++面向?qū)ο蟪绦蛟O計中的多態(tài)性研究[J].計算機工程與應用,2000,36(8):97-98.

[9]Stanley B Lippman.Inside the C++ Object Model[M].侯捷,譯.武漢:華中科技大學出版社,2001.

[10]張亞鵬.關于C++中虛函數(shù)的幾個問題[J].赤峰學院學報:自然科學版,2006(2):132-133.

[11]和力,吳麗賢.關于C++虛函數(shù)底層實現(xiàn)機制的研究與分析[J].計算機工程與設計,2008,29(10):2 705-2 707.

[12]Scott Mayers.More Effective C++ [M].2nd Edition.Addi-sion Wesley Lonman Inc.,1996.

[13]袁亞麗,肖桂云.C++中虛函數(shù)的實現(xiàn)技術研究[J].河北北方學院學報:自然科學版,2006,22(5):67-69,75.

[14]藍雯飛.C++中的多態(tài)性及其應用[J].計算機時代,1998(7):15-16.

主站蜘蛛池模板: 精品少妇人妻一区二区| 最新午夜男女福利片视频| 激情综合网址| 91人妻在线视频| 91精品视频网站| 亚洲精品午夜天堂网页| 欧美一级夜夜爽www| 日本国产精品一区久久久| 日本高清免费一本在线观看| lhav亚洲精品| 国内精品伊人久久久久7777人| 亚洲视频在线青青| 精品国产www| 又爽又大又黄a级毛片在线视频| 久久精品人妻中文视频| 午夜不卡视频| 国产精品久久久久久久伊一| 日韩一二三区视频精品| 成人一区在线| 国产精品所毛片视频| 不卡无码网| 精品无码国产一区二区三区AV| 日本www在线视频| 欧美97欧美综合色伦图| 91在线一9|永久视频在线| 国产日韩欧美在线视频免费观看| 在线观看精品国产入口| 四虎综合网| 亚洲精品无码不卡在线播放| 激情综合婷婷丁香五月尤物| 国产精品无码翘臀在线看纯欲| 真实国产乱子伦视频| a级毛片免费看| 国产一区二区福利| 激情乱人伦| 国产一区成人| 2021国产v亚洲v天堂无码| 青青青国产视频| 国产日韩久久久久无码精品| 波多野结衣亚洲一区| 99在线视频免费| 成人综合网址| 麻豆精品在线视频| 18禁黄无遮挡网站| 国产成人欧美| 免费看a级毛片| 欧美成人精品一级在线观看| 91精品视频在线播放| 久久久久亚洲AV成人人电影软件| 久久青草免费91观看| 精品国产网| 99九九成人免费视频精品| 99久久亚洲综合精品TS| 最新国产精品鲁鲁免费视频| 亚洲AⅤ综合在线欧美一区| 97在线碰| 日本三级欧美三级| 欧美成人a∨视频免费观看| 91久久夜色精品国产网站| 久久黄色免费电影| 天堂亚洲网| 日韩欧美中文字幕在线韩免费| 国产性精品| 亚洲制服丝袜第一页| 欧美日韩一区二区在线免费观看| 一区二区无码在线视频| 日韩a在线观看免费观看| 日本在线视频免费| 91娇喘视频| 亚洲第一色网站| 国产经典在线观看一区| 91麻豆精品国产高清在线| 国产99精品久久| 免费毛片a| 亚洲国产精品日韩专区AV| 亚洲精品黄| 免费毛片a| 激情爆乳一区二区| 日韩精品亚洲一区中文字幕| 日韩高清欧美| 91香蕉视频下载网站| 国产成人你懂的在线观看|