版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、文章來源 畢業(yè)論文網(wǎng) 基于c+與虛函數(shù)的多態(tài)性編程實現(xiàn)機制探討文章來源 畢業(yè)論文網(wǎng) 以下是yjbys求職網(wǎng)與您分享的一篇關(guān)于基于c+與虛函數(shù)的多態(tài)性編程實現(xiàn)機制探討的計算機應(yīng)用畢業(yè)論文,歡迎瀏覽! 關(guān)鍵詞: 動態(tài)聯(lián)編;虛函數(shù);多態(tài)性 摘要: 關(guān)于虛函數(shù)能否解決類的派生過程中出現(xiàn)的切片問題,論文結(jié)合具體實例,給出了在c+中利用虛函數(shù)實現(xiàn)程序多態(tài)性的設(shè)計方法,并進(jìn)一步探討了多態(tài)性編程的實現(xiàn)機制。 中圖分類號: tp311 文獻(xiàn)標(biāo)識碼:a 文章編號:1004-633x(2011)12-0061-02 多態(tài)性是面象對象程序設(shè)
2、計的重要特征,封裝性、繼承性和多態(tài)性一起并稱為oop(object oriented programming)的三大特征,多態(tài)性是面象對象編程技術(shù)的核心組件之一。多態(tài)性對于c+的學(xué)習(xí)者來說是學(xué)習(xí)過程中最困難的概念,也是理解oop的轉(zhuǎn)折點1。本文基于具體案例,給出了在c+中利用虛函數(shù)實現(xiàn)面向?qū)ο缶幊痰亩鄳B(tài)性的設(shè)計方法,并進(jìn)一步探討了多態(tài)性編程的實現(xiàn)機制。 1 多態(tài)性與虛函數(shù) 多態(tài)性是指為一個函數(shù)名關(guān)聯(lián)多種含義的能力,即同一種調(diào)用方式可以映像到不同的函數(shù)。這種把函數(shù)的調(diào)用與適當(dāng)?shù)暮瘮?shù)體對應(yīng)的活動又稱為綁定(binding)。根據(jù)綁定所進(jìn)行階段的不同,可分為早期綁定(early
3、binding)、晚期綁定(late binding),早期綁定發(fā)生在程序的編譯階段,稱為靜態(tài)聯(lián)編(static binding),晚期綁定發(fā)生在程序的運行階段,稱為動態(tài)聯(lián)編(dynamic binding)。c+支持基于靜態(tài)聯(lián)編和動態(tài)聯(lián)編的兩種不同的多態(tài)性:編譯時的多態(tài)性和運行時的多態(tài)性。 1.1 編譯期多態(tài) 編譯期多態(tài)在oop中的具體體現(xiàn)是函數(shù)重載(overloading),函數(shù)重載指的是允許多個不同函數(shù)使用同一個函數(shù)名,但要求這些同名函數(shù)具有不同的參數(shù)表(當(dāng)然,函數(shù)體的代碼也不同):參數(shù)表中的參數(shù)個數(shù)不同、參數(shù)表中對應(yīng)的參數(shù)類型不同或參數(shù)表中不同類型參數(shù)的次序不同。&
4、nbsp;系統(tǒng)對函數(shù)重載這種多態(tài)性的分辨與處理是在編譯階段完成的。因為重載函數(shù)的形參表是不同的,因些,在編譯過程中,系統(tǒng)就可以根據(jù)函數(shù)調(diào)用時的實參類型來匹配這些同名的函數(shù),進(jìn)而確定函數(shù)調(diào)用語句實際上對應(yīng)的函數(shù)體代碼(位置),故稱這種多態(tài)性是編譯期多態(tài)。 1.2 運行期多態(tài) 通過動態(tài)聯(lián)編技術(shù),為一個函數(shù)名關(guān)聯(lián)多種含義的能力,稱為運行期多態(tài)性。 為增強多態(tài)性,c+不僅支持函數(shù)的重載,還允許在不同的類中出現(xiàn)其原型完全相同的函數(shù),即所謂的超載。函數(shù)超載(overriding) 是指在基類與其派生類的范圍內(nèi),允許多個不同函數(shù)使用完全相同的函數(shù)名、函數(shù)參數(shù)表和函數(shù)返回類型。函
5、數(shù)的超載在更高的層次上充分體現(xiàn)了程序的多態(tài)性。由于函數(shù)超載允許不同的函數(shù)具有完全相同的函數(shù)原型,因此在編譯階段無法判別此次調(diào)用應(yīng)執(zhí)行哪段函數(shù)代碼。只有到了運行過程執(zhí)行到此處時,本文來自論文之家:,轉(zhuǎn)載請保留此標(biāo)記才有可能臨時判別執(zhí)行哪一段函數(shù)代碼,即動態(tài)聯(lián)編。函數(shù)的超載需要動態(tài)聯(lián)編技術(shù)的支持,而動態(tài)聯(lián)編是通過虛函數(shù)來實現(xiàn)的。 1.3虛函數(shù)(virtual function) 在定義某一基類(或其派生類)時,若將其中的某一個非靜態(tài)成員函數(shù)的屬性說明為virtual,則稱該函數(shù)為虛函數(shù)。 虛函數(shù)的使用與函數(shù)超載密切相關(guān)2。第一,基類中某函數(shù)被說明為虛函數(shù);第二,其派生
6、類中又用到與該函數(shù)同一接口,但函數(shù)體不同的超載函數(shù)。二者齊備,當(dāng)編譯到對此函數(shù)的調(diào)用時,相當(dāng)于告訴編譯器:“不用綁定與此函數(shù)名對應(yīng)的具體的函數(shù)代碼段,等到運行時再從具體對象實例中確定它的具體實現(xiàn)。”3這種技術(shù)即晚期綁定技術(shù),這種技術(shù)使得運行期對一個虛函數(shù)的調(diào)用隨著對象實例的變化可以呈現(xiàn)多種結(jié)果,即程序呈現(xiàn)運行期的多態(tài)性。虛函數(shù)是這種運行期多態(tài)性得以實現(xiàn)的必要條件,函數(shù)超載是多態(tài)性的意義所在。 2 利用虛函數(shù)實現(xiàn)程序的多態(tài)性 有了虛函數(shù)的支持就一定能實現(xiàn)動態(tài)聯(lián)編,在程序運行中呈現(xiàn)多態(tài)性嗎?在程序設(shè)計中要采用什么方法才能利用動態(tài)聯(lián)編技術(shù),體現(xiàn)程序的多態(tài)性
7、呢?下面分三種情況討論。 (1)虛函數(shù)并不是程序多態(tài)的充分條件。下面程序1中類的成員函數(shù)雖聲明為虛函數(shù),但仍發(fā)生了切片問題3。 程序1 #include<iostream> #include<string> using namespace std; class pet public: string name; virtual void print(); class dog:public pet public: string breed;&n
8、bsp;virtual void print(); void main() pet pet_object; dog dog_object; dog_="珍妮" dog_object.breed="great dane" pet_object =dog_object; pet_object.print();/切片問題, void pet:print() cout<<"寵物名字:"<
9、<name<<endl; void dog:print() cout<<"寵物名字:"<<name<<endl; cout<<"寵物品種:"<<breed<<endl; 雖然程序中將一個派生類寵物狗對象dog_object賦給了一個基類寵物對象pet_object,但調(diào)用虛函數(shù)print()時,并沒有隨著對象實例的變化而呈現(xiàn)多態(tài)現(xiàn)象,從而去綁定派生類對象的虛函數(shù)。程序的運行結(jié)果是:“寵物名字:珍妮&rd
10、quo;,沒有輸出派生類寵物狗對象dog_object所有的屬性值,而是切去了派生類新增部分的屬性,出現(xiàn)了切片問題。 (2)在程序設(shè)計中,將類及其派生類重載的成員函數(shù)聲明為虛函數(shù),再利用派生類對象初始化基類對象的引用,能實現(xiàn)程序的多態(tài)性,即: baseclass& base_object= derived_object 如程序2所示,銀行允許開設(shè)多種不同的帳戶,下面程序2中為基本銀行帳戶定義了一個基類bankaccount,又定義了兩個派生類marketaccount和 cdaccount,分別代表具有不同取款規(guī)則的帳戶,在每個類中都重載了取款成員函數(shù)wi
11、thdraw(),以適用于所有不同取款規(guī)則的帳戶。轉(zhuǎn)帳操作應(yīng)在所用對象之間進(jìn)行,在完成轉(zhuǎn)帳操作的成員函數(shù)convert()實現(xiàn)代碼中,取款成員函數(shù)withdraw()應(yīng)隨著實例對象(取款帳戶)other的變化而分別綁定不同類的重載的函數(shù)段,則對于重載的成員函數(shù)withdraw()必須采用動態(tài)聯(lián)編的方式進(jìn)行綁定,為此在下面程序中做了這樣的設(shè)計:聲明withdraw()為虛函數(shù); 將轉(zhuǎn)帳函數(shù)convert()的形參設(shè)計成基類對象的引用bankaccount&,當(dāng)轉(zhuǎn)帳函數(shù)以不同的帳戶對象(特別是派生類對象)被調(diào)用時,實際上是用派生類對象初始化了基類對象的引用。程序運行測試結(jié)果達(dá)到了預(yù)期的目的
12、,當(dāng)然,程序中略去了所有其它與本文討論無關(guān)的成員函數(shù)及實現(xiàn)的細(xì)節(jié),將存款函數(shù)聲明為虛函數(shù)也不是必須的,這是為了下節(jié)說明的方便。 程序2 #include<iostream> #include<cstring> using namespace std; class bankaccount char name80; double balance; public: bankaccount(char ,double); virtual void deposit(double amount
13、); virtual bool withdraw(double); void convert(bankaccount&,int ); class marketaccount :public bankaccount int withdraw_numbers; public: marketaccount(char ,double); virtual bool withdraw(double ) class cdaccount:public bankaccount&
14、nbsp; double interest_rate; public: cdaccount(char ,double,double); virtual bool withdraw(double ); bool bankaccount :withdraw(double amount) balance-=amount; return 1; bool cdaccount :withdraw(double amount) cout<<"提前取款,罰利息的25%n&
15、quot; double temp=amount+get_balance() *interest_rate/100; balance-=temp; return 1; bool marketaccount :withdraw(double amount) cout<<"取款交手續(xù)費1.5n; balance-=amount+1.5; return 1; /將other帳戶的錢轉(zhuǎn)至當(dāng)前帳戶 void bankaccount:convert (bank
16、account& other,int amount) other.withdraw(amount) deposit(amount); / ……(略去其余函數(shù)的實現(xiàn)部分) void main() cdaccount zhang ("張華",1000,3); marketaccount wang ("王芳",300); wang.convert(zhang ,500); (3)程序設(shè)計中,將類及其派生類重載的成員函數(shù)
17、聲明為虛函數(shù),利用指向基類和派生類指針的賦值兼容性,實現(xiàn)程序的多態(tài)性,即: baseclass * base_object _point=&derived_object 真對上述程序2,只須將轉(zhuǎn)帳函數(shù)的參數(shù)類型改為指向基類對象的指針,并作如下調(diào)整: void bankaccount:convert (bankaccount* other,int amount) other->withdraw(amount) deposit(amount); 對函數(shù)調(diào)用時的實參對象要采用對象地址的格式。
18、在以樹形為主要結(jié)構(gòu)的類的派生關(guān)系中,虛函數(shù)是架構(gòu)程序模塊的主要方式,虛函數(shù)在基類中對某種操作提供一個框架,在派生類中為框架提供不同的實現(xiàn),虛函數(shù)的語義決定了只有當(dāng)用父類指針訪問它們時,才能實現(xiàn)運行時的多態(tài)性4,從而解決切片問題。 3 虛函數(shù)的實現(xiàn)機制 c+中的虛函數(shù)是實現(xiàn)面向?qū)ο蟪绦蛟O(shè)計最重要的語言機制,是動態(tài)聯(lián)編技術(shù)實現(xiàn)程序多態(tài)性的基石。但是程序執(zhí)行的時候,代碼已經(jīng)脫離編譯器、鏈接器的干預(yù),那么是誰完成執(zhí)行時的動態(tài)聯(lián)編?背后的技術(shù)是什么? 實際上編譯器在程序靜態(tài)編譯期已經(jīng)做好了必要的準(zhǔn)備:它為每一個包含了虛函數(shù)的類產(chǎn)生一個虛擬函數(shù)表vtab,為該類的所有對象共享
19、;為類的每一個實例對象添加一個指針分量vptr,該指針指向所屬類的虛函數(shù)表vtab5。 虛函數(shù)表vtab中的每一項是一個虛函數(shù)地址,類中的每一個虛函數(shù)都在表中確切的占有一項。程序2中派生類對象cdaccount:zhang的內(nèi)存部局和類的虛函數(shù)表如圖1所示。 在圖1中注意到,編譯器會把指向虛函數(shù)表的指針存放于對象實例最前面的位置,這保證運行時我們可以通過對象實例的地址得到這張?zhí)摵瘮?shù)表,然后就可以遍歷其中的函數(shù)指針,并調(diào)用相應(yīng)的虛函數(shù)。在程序2的主函數(shù)中增加如下代碼: typedef void(*fun)(void); fun pfun=null; /由對象zhang的地址得到對象頭部的指針分量 cout<<(int*)(&zhang)<<endl; /取得虛函數(shù)表vtab的地址 cout<<(int*)*(int*)(&zhang)<<endl;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 中國東方航空采購合同模板
- 碳捕獲和儲存相關(guān)行業(yè)項目成效實現(xiàn)方案
- 數(shù)字化教育資源平臺相關(guān)行業(yè)項目操作方案
- 智能視覺教育相關(guān)行業(yè)項目操作方案
- 2024年中國鑄鏈板式電阻爐市場調(diào)查研究報告
- 2024年中國立式滅菌器市場調(diào)查研究報告
- 2024年中國家紡包裝袋市場調(diào)查研究報告
- 2024年高溫壓輥項目可行性研究報告
- 2024年瀝青灑布拖車項目可行性研究報告
- 2024年智能交通管理平臺項目可行性研究報告
- 《奶茶店員工手冊》
- 三角函數(shù)的圖像與性質(zhì)專項訓(xùn)練(解析版)
- 2024年浙江浙能電力股份有限公司招聘筆試參考題庫含答案解析
- ICU常用的評估工具(疼痛、鎮(zhèn)靜、譫妄)
- WDM網(wǎng)絡(luò)規(guī)劃與設(shè)計指南
- 沈陽某項目結(jié)構(gòu)顧問設(shè)計任務(wù)書
- 房屋裝修合同及預(yù)算清單【精校】.doc
- 高等電磁理論
- 胃癌正式講解(課堂PPT)
- 危險性較大分部分項工程及施工現(xiàn)場易發(fā)生重大事故的部位環(huán)節(jié)的預(yù)防監(jiān)控措施和應(yīng)急預(yù)案11匯編
- DF1910使用說明書
評論
0/150
提交評論