版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、第十一章 多態(tài)性和虛函數(shù)(2)應用與討論面向?qū)ο蟪绦蛟O計(C+)11.8 構(gòu)造抽象接口多態(tài)性的優(yōu)點之一11.8.1 問題描述 傳達員:下午在會議室開會!項目規(guī)劃公司發(fā)展策略11.8.2 靜態(tài)綁定下的實現(xiàn) 傳達員只負責通知某時某地開會,至于開什么會,怎么開,他才不管呢。 然而實現(xiàn)時,程序員必須分清楚通知的對象是誰?然后決定應該調(diào)用那一個對象的“開會函數(shù)”。switch(emp_type) case “CTO”: (CTO_manager *)emp)- meeting(); break; case “Chair”: (Chair_manager *)emp)-meeting(); break;
2、default: ERROR();11.8.3 動態(tài)綁定下的實現(xiàn)項目規(guī)劃公司發(fā)展策略傳達員:下午在會議室開會!11.8.3 動態(tài)綁定下的實現(xiàn)(續(xù))CTO cto;Manager * pman ;pman = &cto; / 把所有的派生類對象當成基類處理pman - meeting() ; / 通過抽象接口實現(xiàn) 11.9 提高模塊的獨立性多態(tài)性的優(yōu)點之二:可擴展性好11.9.1 靜態(tài)綁定下的擴充討論: 當需求發(fā)生變化時, 如何修改代碼? 設置line的type時必須問一下:“嘿, 我可以設成L么? 修改enum shape_type = P,C,Y,L; 定義Line類; 修改函數(shù) draw_
3、all(),由于switch邏輯的存在,因此代碼的修改量是呈組合數(shù)量級增長的。因此,可擴展性很不好!11.9.2 動態(tài)綁定下的擴充 現(xiàn)在要增加類Line,只需要:從基類Shape中派生出Line類;無需設置類型域,無需改變其它任何的代碼!class Line : public Shape public: Line( Point s,Point e ):start(s),end(e); void setLine( int, int, int , int ); int getX1() const return x1; int getY1() const return y1; int getX2()
4、 const return x2; int getY2() const return y2; virtual void printShapeName() const cout “Line: ; virtual void draw();protected: Point start, end; ;增加line類修改main()函數(shù) (沒有任何變化)int main() Point point1( 7, 11 ); / create a Point Circle circle1( 3.5, 22, 8 ); / create a Circle Cylinder cylinder1( 10, 3.3,
5、 10, 10 ); / create a Cylinder Circle circle2(2.5,10,15); /create a Circle Shape *arrayOfShapes 5 ; / array of base-class pointers arrayOfShapes 0 = &point1; arrayOfShapes 1 = &circle1; arrayOfShapes 2 = &cylinder1; arrayOfShapes 3 = &cycle2; for(int i=0; idraw(); / 動態(tài)關(guān)聯(lián) 也就是說,假如只是增加類 Line,而沒有創(chuàng)建該類的對象
6、,程序不需要做任何其它修改!增加Line對象后的main()函數(shù)(有細微的變化)int main() Point point1( 7, 11 ); / create a Point Circle circle1( 3.5, 22, 8 ); / create a Circle Cylinder cylinder1( 10, 3.3, 10, 10 ); / create a Cylinder Circle circle2(2.5,10,15); /create a Circle Line line(7,10,20,25); Shape *arrayOfShapes 5 ; / array of
7、 base-class pointers arrayOfShapes 0 = &point1; arrayOfShapes 1 = &circle1; arrayOfShapes 2 = &cylinder1; arrayOfShapes 3 = &cycle2; arrayOfShaoes 4 = &line; for(int i=0; idraw(); / 動態(tài)關(guān)聯(lián) 即使需要創(chuàng)建類Line的對象,這種更改也是很容易實現(xiàn)的!習題 (30分鐘內(nèi)完成)信息學院教學辦隨機抽取100名學院的學生到中國科學院實習,他們來自不同的系:CS、Auto、和EE;但教學辦并不知道他們應該到那個所實習。事實上,
8、計算機系的學生知道自己應該到軟件所實習,自動化系到自動化所,電子工程系到電子所。假設每個學生在實習時首先要進行自我介紹。請編程模擬上述過程。 具體要求為:1. 設計學生類,信息包含姓名(8字節(jié)字符)、學號(8字節(jié)字符)、自我介紹(動態(tài)申請內(nèi)存空間);學生的學號在對象生成時由程序統(tǒng)一設定,要求學號不重復; 2. 可以以下列方式產(chǎn)生學生對象: Cstudent stu1(“Mike”); / 僅設定姓名; Cstudent stu2(“Rick”, “I am rick , from USTC” ); / 僅設定姓名和自我介紹。 Cstudent stu3(stu2); / 從一個對象初始化另一個
9、對象,表示的是兩個學生同 / 名,自我介紹內(nèi)容也相同。3. 允許兩個學生對象之間的賦值操作。如:stu1=stu2; 僅表示用stu2的自我介紹 內(nèi)容設置stu1的自我介紹;4. 成員函數(shù)setmessage(char * )設置自我介紹內(nèi)容; getmessage()獲取自我介 紹內(nèi)容;pratice()表示實習過程。11.10 防止組合爆炸 當存在多個類型相互組合的情況時,靜態(tài)綁定下的switch邏輯將會出現(xiàn)“組合爆炸”。 而動態(tài)綁定下的代碼擴充量則是“線性的”。11.10.1 引言:表達式求值+-5*124-5 + 12 * 4 可用表達式樹來表示: 則表達式的值可按二叉樹的后序遍歷進行
10、計算,即先計算左子樹的值和右子樹的值,然后再計算結(jié)點的值。類的層次圖結(jié)點類整形常量類負號運算符類雙目運算符類加運算符類乘運算符類11.10.2 討論:靜態(tài)綁定的表達式求值求某個結(jié)點的值時,由于向上類型轉(zhuǎn)換,結(jié)點的類型都變成Node *,因此,必須依賴switch邏輯判斷左子樹和右子樹結(jié)點的類型,才能正確地綁定到左右子結(jié)點的求值函數(shù),最后得到根結(jié)點的值。 class Plus: public Binop / 加運算符類public: Plus(Node *l, Node * r) :Binop(l,r) int eval() switch ( left-type) case P : switch
11、(right - type) case P: return(Plus*)left-eval()+(Plus*)right-eval(); break; case M: return(Plus*)left-eval()+(Minus*)right-eval(); break; ; ; case M : ; case U : ; ;共需要判斷 n*n中情況11.10.3 動態(tài)綁定的表達式求值 動態(tài)綁定能消除switch邏輯,因此,求任意類型的結(jié)點N的值,可通過:1.向上類型轉(zhuǎn)換:Node * np = N;2.動態(tài)綁定: np -eval() = (np-left)-eval() * (np-ri
12、ght)-eval();注:為簡單起見,架設表達式中僅可能出現(xiàn)-(負號)、+(加運算)、*(乘運算)三種運算符、以及整形常量運算數(shù)。1. 設計結(jié)點的類層次結(jié)點類整形常量類負號運算符類雙目運算符類加運算符類乘運算符類2. 實現(xiàn)各個結(jié)點類及主函數(shù)class Node / 基類,結(jié)點類 public: Node(); virtual Node() ; virtual int eval() error(); return 0; / 計算結(jié)點的值 ;派生類定義:class Binop:public Node /雙目運算符public: Node * left, * right ; Binop() del
13、ete left; delete right ; Binop(Node *l, Node *r) left =l; /左結(jié)點 right = r; /右結(jié)點 ;class Plus: public Binop / 加運算符類public: Plus(Node *l, Node * r) :Binop(l,r) int eval() return left- eval() + right - eval() ; ;派生類定義(續(xù)):class Times:public Binop / 乘運算符類public: Times(Node *l, Node *r ) : Binop (l,r) int e
14、val() return left- eval() * right - eval() ; ;class Uminus:public Node / 負號運算符類 Node * operand ;public: Uminus(Node * op) operand = op ; Uminus() delete operand ; int eval() return operand - eval() ; ;主函數(shù)定義(續(xù)):class Int : public Node int value; public: int(int v) value = v; int eval() return value;
15、;int main() Node * np = new Plus ( new Uminus(new Int(5) , new Times (new int(12) ,new Int(4) );int result = np - eval () ;delete np; cout eval() - right - eval() ; ;class Divide:public Binop / 除運算符類public: Divide(Node *l, Node *r ) : Binop (l,r) int eval() return left- eval() / right - eval() ; 1。模
16、塊獨立性強; 2。代碼的增加是線性的。11.10.4 討論:交互式表達式計算需要編譯器的lex和yacc支持:根據(jù)用戶輸入的表達式動態(tài)產(chǎn)生表達式樹。具體實現(xiàn)(略):參見編譯原理詞法分析和語法分析相關(guān)章節(jié)。11.10.5 討論:如何支持混合運算假設結(jié)點中可能有復數(shù),并且允許復數(shù)和整數(shù)的混合運算,該如何處理? 例如:np1+np2有四種可能: 1):復數(shù) + 復數(shù) 2):整數(shù) + 復數(shù) 3):復數(shù) + 整數(shù) 4):整數(shù) + 整數(shù) 11.11 虛運算符重載函數(shù)注 多重指派技術(shù):虛函數(shù)與運算符重載函數(shù)的完美結(jié)合!注:參見15.12節(jié)11.11.1 問題:混合運算矩陣、向量和標量混合*(乘)運算: M1
17、 * M2 ; 其中M1和M2是兩個基類指針思路一:虛函數(shù)分析:虛函數(shù)的本質(zhì)是能夠動態(tài)確定一個對象的類型,而由于 m1*m2m1.operator*(m2)中存在兩個未確定的類型。因此,試圖依賴一次虛函數(shù)調(diào)用無法同時動態(tài)確定m1和m2的類型; 思路二:重載“+”分析:由于重載函數(shù)是必須依賴參數(shù)來決定確定具體調(diào)用的版本。而 m1*m2( m1.operator*(m2)中,m1可以通過虛函數(shù)動態(tài)綁定,但m2的類型尚未確定。因此單純依賴重載函數(shù)不能解決。思路三:兩者結(jié)合(多重指派技術(shù))(不妨設為 Matrix * Vector)2. 定義重載函數(shù): virtual multiply(Matrix
18、*) 計算M*V ; virtual multiply(Vector *) 計算V*V ; virtual multiply(Scalar *) 計算S*V;1. 定義virtual operator *; 通過調(diào)用m1.operator*(m2)動態(tài)綁定m1到Matrix*。3. 在m1.operator*(m2)中調(diào)用m2.multiply(m1) m2.multiply(Matrix *);該函數(shù)將動態(tài)綁定到Vector的mutiply(Matrix *);11.11.2 多重指派:程序的實現(xiàn)(demo)class Matrix; / 矩陣類class Scalar; / 標量類clas
19、s Vector; / 矢量類class Math / 基類 Mathpublic: / 一次指派,確定m1的類型 virtual Math& operator*(Math& rv) = 0; / 二次指派,確定m2的類型 virtual Math& multiply(Matrix*) = 0; virtual Math& multiply(Scalar*) = 0; virtual Math& multiply(Vector*) = 0; virtual Math() ;class Matrix : public Math public: / 一次指派 Math& operator*(Mat
20、h& rv) return rv.multiply(this); / 二次指派 Math& multiply(Matrix*) cout “Matrix * Matrix” endl; return *this; Math& multiply(Scalar*) cout Scalar * Matrix endl; return *this; Math& multiply(Vector*) cout Vector * Matrix endl; return *this; ;class Scalar : public Math public: / 一次指派 Math& operator*(Math& rv) return rv.multiply(this); / 二次指派 Math& multiply(Matrix*) cout Matrix * Scalar endl; return *this; Math& multiply(Scalar*) cout Scalar * Scalar endl; return *this; Math& multiply(Vector*) cout Vector * Scalar endl; return *this; ;class Vector : public Math public: /
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版物業(yè)管理區(qū)域消防安全管理合同3篇
- 二零二五年度個人額度借款合同與金融科技合作
- 二零二五年度社保工傷保險合同范本(含員工離職手續(xù))3篇
- 醫(yī)療垃圾處理合同
- 2025年度個人股權(quán)質(zhì)押股權(quán)信托服務合同(信托保障版)4篇
- 2025年全球及中國數(shù)據(jù)中心機器人行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025-2030全球制冷空調(diào)熱力膨脹閥行業(yè)調(diào)研及趨勢分析報告
- 二零二五年度健康產(chǎn)品綠色促銷合作協(xié)議書2篇
- 2023年員工三級安全培訓考試題及完整答案【必刷】
- 2024年公司項目部負責人安全教育培訓試題答案AB卷
- 2025-2030年中國雪茄市場運行現(xiàn)狀及投資發(fā)展前景預測報告
- 《水利工程安全管理》課件
- 三年級數(shù)學(上)計算題專項練習附答案
- 中外美術(shù)史試題及答案
- 《架空輸電線路導線舞動風偏故障告警系統(tǒng)技術(shù)導則》
- 2024年計算機二級WPS考試題庫
- 廣東省廣州黃埔區(qū)2023-2024學年八年級上學期期末數(shù)學試卷(含答案)
- 工會換屆公示文件模板
- 江蘇省南京市協(xié)同體七校2024-2025學年高三上學期期中聯(lián)合考試英語試題答案
- 青島版二年級下冊三位數(shù)加減三位數(shù)豎式計算題200道及答案
- 法理學課件馬工程
評論
0/150
提交評論