9继承和多态 应用和示例

上传人:m**** 文档编号:568522674 上传时间:2024-07-25 格式:PDF 页数:63 大小:636.46KB
返回 下载 相关 举报
9继承和多态 应用和示例_第1页
第1页 / 共63页
9继承和多态 应用和示例_第2页
第2页 / 共63页
9继承和多态 应用和示例_第3页
第3页 / 共63页
9继承和多态 应用和示例_第4页
第4页 / 共63页
9继承和多态 应用和示例_第5页
第5页 / 共63页
点击查看更多>>
资源描述

《9继承和多态 应用和示例》由会员分享,可在线阅读,更多相关《9继承和多态 应用和示例(63页珍藏版)》请在金锄头文库上搜索。

1、继承和多态 应用和示例闫哲闫哲2005年年6月月24日日内容? 继承的内存布局继承的内存布局? 赋值相容规则赋值相容规则? 继承举例继承举例? 虚函数实现原理虚函数实现原理? 多态性举例多态性举例? 设计模式设计模式继承的内存布局? 通过继承,派生类中包含基类成员通过继承,派生类中包含基类成员class Point2dpublic:Point2d() / /protected:float x,y;class Point3d: public Point2dpublic:Point3d():Point2d() / /private: float z;Point3d obj2;Point2d obj

2、1;float xfloat yfloat zfloat xfloat y基类成员基类成员private:构造函数和析构函数的调用顺序构造函数和析构函数的调用顺序访问权限的理解访问权限的理解继承的内存布局? 对比:对象成员对比:对象成员class Point2dpublic:Point2d() / /protected:float x,y;class Point3d: public:Point3d():point() / /private: Point2d point;float z;Point3d obj2;Point2d obj1;float xfloat yfloat zfloat xf

3、loat ypoint对象成员对象成员赋值相同规则? 通过公有继承,派生类的对象可以当作基类使用通过公有继承,派生类的对象可以当作基类使用class Point2dpublic: void show();protected:float x,y;class Point3d: public Point2dpublic: void show();private: float z;void main()Point2d obj2d;Point3d obj3d;obj2d=obj3d; /对象赋值对象赋值obj2d.show(); /调用调用Point2d:show()Point3d obj3d;Poin

4、t2d obj2d;float xfloat yfloat zfloat xfloat y派生类对象赋值给基类对象派生类对象赋值给基类对象向上映射、对象切片向上映射、对象切片赋值相同规则? 通过公有继承,派生类指针可以赋给基类指针通过公有继承,派生类指针可以赋给基类指针class Point2dpublic: void show();protected:float x,y;class Point3d: public Point2dpublic: void show();private: float z;void main()Point2d obj2d;Point3d obj3d;Point3d

5、 obj3d;Point2d obj2d;p3dp2dfloat xfloat yfloat zfloat xfloat yp2d/指针赋值指针赋值Point2d *p2d=&obj2d;Point3d *p3d=&obj3d;p2d=p3d;p2d-show(); 调用调用Point2d:show()多重继承的内存布局? 通过多重继承,派生类中包含各基类成员通过多重继承,派生类中包含各基类成员class Point2dpublic: /protected: float x,y;class Point3d: public Point2dpublic: /protected: float z;c

6、lass Vertexpublic: /protected: Vertex* next;class Vertex3d: public Point3d, public Vertexpublic: /protected: float mumble;Point2dPoint3dVertex3dVertex多重继承的内存布局float xfloat yfloat zVertex* nextfloat xfloat yfloat zPoint2d子对象子对象Point3d子对象子对象Point2d子对象子对象Vertex子对象子对象Point3d obj1;float mumbleVertex* nex

7、tVertex3d obj3;Vertex obj2;/对象赋值对象赋值obj1=obj3;obj2=obj3;/指针赋值指针赋值Point3d *p3d=&obj3;Vertex *pv=&obj3; /涉及指针偏移涉及指针偏移赋值相容规则:赋值相容规则:多重继承的内存布局? 多重继承中数据成员的二义性多重继承中数据成员的二义性int memberint memberint total来自base1class base1protected: int member;public: base1() / ;class base2protected: int member;public: base2

8、() / ;class derived: public base1, public base2private: int total;public: derived() / void func() member=0; /二义性 ; 来自base2derived对象布局base1:member=0;base2:member=0;多重继承的内存布局? 虚拟基类之前的内存布局虚拟基类之前的内存布局int bint b2class baseprotected: int b;class base1: public baseprotected: int b1;class base2: public base

9、protected: int b2;class derived: public base1, public base2float d;public: int fun();int bint b1base2的内存布局的内存布局base1的内存布局的内存布局int bint b1int bint b2float d二义性二义性derived的内存布局的内存布局不能把不能把derived对象当对象当base对象使用对象使用多重继承的内存布局通过指针指向共享的虚拟基类通过指针指向共享的虚拟基类? 虚拟基类的内存布局虚拟基类的内存布局int b2int bclass baseprotected: int

10、b;class base1: virtual public baseprotected: int b1;class base2: virtual public baseprotected: int b2;class derived: public base1, public base2float d;public: int fun();int b1int bbase* pbase* pbase1的内存布局的内存布局base2的内存布局的内存布局int b1int b2float dint bbase* pbase* pderived的内存布局的内存布局可以把可以把derived对象当对象当ba

11、se对象使用对象使用继承的使用? 从现实中捕获一般从现实中捕获一般-特殊关系特殊关系class Automobilepublic: Automobile();void start();void stop();void speedup();void speeddown();protected: char* brand;float price;float speed;class Car: public Automobilepublic: Car();void absstop();private: float gas_comsume; class Jeep: public Automobilepub

12、lic: Jeep();void climb();private: int drive;class Truck: public Automobilepublic: Truck();void transport();private: float load;AutomobileCarJeepTruck继承的使用? 从相似的类中提取共同的特征,形成类层次从相似的类中提取共同的特征,形成类层次在银行业务中,有储蓄在银行业务中,有储蓄(Saving)账户和结算账户和结算(Checking)账户之分,两个类的设计:账户之分,两个类的设计:SavingaccNumberbalanceSaving()With

13、draw()Deposit()Display()CheckingaccNumberbalanceremittanceChecking()Withdraw()Deposit()Display()SetRemit()Consume()储蓄账户储蓄账户结算账户结算账户继承的使用/类的定义省略#includeSaving:Saving(int accNo,float bal=0)accNumber=accNo; balance=bal;void Saving:Withdraw(float bal)if(bal0) balance-=bal; void Saving:Deposit(float bal)

14、if(bal0) balance+=bal; void Saving:Display()cout“Saving Account”accNo“:”balanceendl; Checking:Checking(int accNo,float bal=0)accNumber=accNo; balance=bal; void Checking:Withdraw(float bal)float tmp; / 根据remit值计算tmpif(tmp0) balance-=tmp;void Checking:Deposit(float bal)if(bal0) balance+=bal; void Chec

15、king:Display()cout“Saving Account”accNo“:”balanceendl; void Checking:SetRemit(int rem)remittance=rem; void Checking:Consume(float price,float add=0)float tmp=price+add;if(tmp0) balance-=tmp;继承的使用? Checking类继承类继承Saving类类SavingaccNumberbalanceSaving()Withdraw()Deposit()Display()CheckingremittanceCheck

16、ing()Withdraw()SetRemit()Consume()储蓄账户储蓄账户结算账户结算账户继承的使用class Savingprotected:int accNumber;float balance;public: Saving(int accNo,float bal=0);void Withdraw(float bal);void Deposit(float bal);void Display();class Checking: public Savingprivate: int remittance;public: Checking(int accNo,float bal=0);

17、void Withdraw(float bal);void setRemit(int rem);void Consume(float price, float add);#include/Saving的实现Checking:Checking(int accNo,float bal=0): Saving(accNo,bal)void Checking:Withdraw(float bal)float tmp;/根据remit计算if(tmp0)balance-=tmp;void Checking:setRemit(int rem)remittance=remit;Void Checking:Co

18、nsume(float price,float add=0)float tmp=price+add;if(tmp0) balance-=tmp;继承的使用? 思考继承关系:结算帐户思考继承关系:结算帐户 is-a 储蓄帐户吗?储蓄帐户吗?SavingChecking增加数据成员增加数据成员overdraft表示透支范围表示透支范围在在Withdraw()中允许透支中允许透支则则Checking也得到了该数据成员也得到了该数据成员其实,其实,Checking不是一种不是一种Saving,而是不同类型的两种帐户而是不同类型的两种帐户AccountaccNumberbalanceAccount()W

19、ithdraw()Deposit()Display()SavingoverdraftSaving()Withdraw()CheckingremittanceChecking()Withdraw()setRemit()Consume()继承的使用class Accountprotected: int accNumber;float balance;public: Account(int accNo,float bal=0);virtual void Withdraw(float bal);void Deposit(float bal);void Display();class Saving: p

20、ublic Accountprivate: float overdraft;public: Saving(int accNo,float bal=0): Account(accNo,bal)void Withdraw(float bal);class Checking: public Accountprivate: int remittance;public: Checking(int accNo,float bal=0):Account(accNo,bal)void Withdraw(float bal);void setRemit(int remit);void Consume(float

21、 price,float add);virtual void Withdraw(float bal)=0;Account、Saving、Checking之间的层次关系符合现实之间的层次关系符合现实Saving和和Checking可独立变化可独立变化继承的使用? 现实世界中的类层次现实世界中的类层次PersonStudentTeacherCollegeStudentGraduateStudentInstructorProfessorGoodsBookMusicMovieComputerEconomicsLiteraturepopularclassiccartoon继承的使用? 现实世界中的类层次

22、现实世界中的类层次EmployeeManagerStaffConsultantFulltime ParttimeProductFruitDairyMeetMilkButterPorkBeefAppleWaterm价格调整策略:价格调整策略:数据成员数据成员supply和和demand成员函数成员函数pricechange()不同商品计算价格变动不同商品计算价格变动继承的使用? 纸牌游戏问题纸牌游戏问题?设计设计CardGame类用来表示普通的类用来表示普通的52张纸牌,有四种花色张纸牌,有四种花色(红心红心/方块方块/梅花梅花/黑桃黑桃),各,各13张,用适当的方式实现纸牌的基本功能。张,用适

23、当的方式实现纸牌的基本功能。?从从CardGame类派生出类派生出Bridge类,为类,为Bridge类设计类设计deal函数,用来将纸牌分给函数,用来将纸牌分给4人,每人人,每人13张;张;?从从CardGame类派生出类派生出Poker类,为类,为Poker类设计类设计deal函数,用来将纸牌分给函数,用来将纸牌分给n(27)人,每人人,每人5张。张。?最后编写测试程序。最后编写测试程序。CardGameBridgePoker继承的使用enum CardTypeHeart,Diamond,Club,Spade;/红心、方块、梅花、黑桃struct CardCardType type;int

24、 no;class CardGameprotected: Card cards52;int remain; /发牌后剩余张数int persons; /玩牌人数void showCard(Card);public: CardGame(int p_num=4);void wash();void deal();void display();class Bridge: public CardGamepublic:Bridge();void deal();class Poker: public CardGamepublic:Poker(int p_num=4);void deal();继承的使用voi

25、d CardGame:wash() /洗牌Card temp52;for(int i=0;i52;i+) tempi=cardsi;for(i=0;i52;i+)int location=(int)(52*rand()/(float)RAND_MAX);while(!templocation.no)location=(int)(52*rand()/(float)RAND_MAX);cardsi=templocation;templocation.no=0; remain=52;void CardGame:showCard(Card c)cout(char)(c.type+3)1 & c.no1

26、1) coutc.no;else if(c.no=1) coutA;else if(c.no=11) coutJ;else if(c.no=12) coutQ;else if(c.no=13) coutK;#include#include#includeCardGame.h“CardGame:CardGame(int p_num)for(int i=0;i4;i+) /CardTypefor(int j=0;j13;j+) /CardNocardsi*13+j.type=(CardType)i;cardsi*13+j.no=j+1;remain=52;persons=p_num;void Ca

27、rdGame:display()cout=Cards=endl;for(int i=0;i52;i+)showCard(cardsi);if(i+1)%13=0) coutendl;cout=Cards=endl;继承的使用void Poker:deal()if(remainpersons*5)/先检查是否够发cout余牌不足,请重新洗牌!endl;return;for(int i=0;ipersons;i+)coutPersoni+1: endfor(int j=0;j5;j+)showCard(cards52-remain+j*persons+i);coutendl; /for perso

28、nsremain=remain-5*persons;void main()Bridge b_game; b_game.display();b_game.wash(); b_game.deal();Poker p_game(5); p_game.wash();p_game.display(); p_game.deal();p_game.deal();Bridge:Bridge()void Bridge:deal()coutFirst Person: endl;for(int i=0;i13;i+)showCard(cardsi*4); coutendl;coutSecond Person: en

29、dl;for(i=0;i13;i+)showCard(cardsi*4+1); coutendl;coutThird Person: endl;for(i=0;i13;i+) showCard(cardsi*4+2); coutendl;coutFourth Person: endl;for(i=0;i13;i+)showCard(cardsi*4+3); coutendl;remain=0;Poker:Poker(int p_num):CardGame(p_num)虚函数原理? 虚函数表虚函数表vtbl及其指针及其指针vptrPoint的内存布局的内存布局class Pointpublic:

30、 virtual Point();virtual Point& mult(float)=0;float x() return _x; virtual float y() return 0; virtual float z() return 0; protected:Point(float x=0.0);float _x;_xvptr_Pointtype_info for Point#0#1#2#3#4Point:Point()纯虚函数纯虚函数Point:y()Point:z()虚拟表虚拟表vtable虚函数原理? 派生类覆盖定义虚函数派生类覆盖定义虚函数class Point2d: publi

31、c Pointpublic: Point2d(float xf=0.0, float yf=0.0): Point(xf) _y=yf; Point2d();Point2d& mult(float);float y() return _y; protected: float _y;虚拟表虚拟表vtablePoint2d的内存布局的内存布局type_info for Point2d_xvptr_Point_y#0#1#2#3#4Point2d:Point2d()Point2d:mult(float)Point2d:y()Point:z()虚函数原理? 派生类覆盖定义虚函数派生类覆盖定义虚函数cl

32、ass Point3d: public Point2dpublic: Point3d(float xf=0.0, float yf=0.0, float zf=0.0): Point2d(xf,yf) _z=zf; Point3d();Point3d& mult(float);float z() return _z; protected: float _z;虚拟表虚拟表vtablePoint3d的内存布局的内存布局type_info for Point3d_xvptr_Point_y_z#0#1#2#3#4Point3d:Point3d()Point3d:mult(float)Point2d:

33、y()Point3d:z()虚函数原理? 通过基类指针或引用调用虚函数通过基类指针或引用调用虚函数_xvptr_yvoid main()Point2d obj2d;Point3d obj3d;Point* p=&obj2d;coutz();p=&obj3d;coutz();Point2d虚拟表虚拟表vtabletype_info for Point2d#0Point2d:Point2d()#1Point2d:mult(float)#2obj2dPoint2d:y()#3Point:z()#4p-z(); 转化成转化成(*p-vptr4)(p);type_info for Point3dPoin

34、t3d:Point3d()Point3d:mult(float)Point2d:y()Point3d:z()Point3d虚拟表虚拟表vtable#0#1#2#3#4_xvptr_yobj3d_z虚函数原理? 通过基类对象调用虚函数?静态联编通过基类对象调用虚函数?静态联编/假设修改假设修改Point定义:定义:/去掉纯虚函数,改为公有构造去掉纯虚函数,改为公有构造void main()Point obj;Point2d obj2d;obj=obj2d; /静态联编静态联编coutobj.y();Point* p=&obj;couty(); /动态联编动态联编x_Point2dy_Point2

35、dx_Pointobjobj2dvptr_Pointvptr_Point2dPoint虚拟表虚拟表x_Point2dvptr_Pointvtbl赋值后的赋值后的obj虚函数原理? 非虚函数的调用?静态联编非虚函数的调用?静态联编/假设假设Point增加非虚函数增加非虚函数Show()/Point2d和和Point3d分别覆盖定义分别覆盖定义void main()Point2d obj2d;Point* p=&obj2d;p-show();x_Point2dy_Point2dobj2dvptr_Point2dpp-show()进行静态联编进行静态联编(*p).show();虚函数原理? 派生类要

36、覆盖定义虚函数派生类要覆盖定义虚函数type_info1#includeclass Basepublic: virtual void fn(int x)cout“In Base Class,x=”xendl;class Derived: public Basepublic: void fn(float x)cout“In Derived Class,x=”xendl;void test(Base& b)int i=1; b.fn(i);float f=2.0; b.fn(f); vptrBase:fnBase对象对象Base的vtblvptrBase:fnDerived对象对象type_inf

37、o2Derived的vtbl没有覆盖定义没有覆盖定义虚函数原理? 同名函数分类:同名函数分类:?重载(重载(overload):相同作用域内名字相同参数不同):相同作用域内名字相同参数不同?覆盖、改写(覆盖、改写(override):派生类中覆盖定义):派生类中覆盖定义?隐藏(隐藏(hide):内部作用域中屏蔽外部同名函数):内部作用域中屏蔽外部同名函数#includeclass basepublic: virtual void f()cout“base:f”endl;virtual void f(int a) cout“base:f-”aendl;class derived: public

38、basepublic: virtual void f(float b)cout“derived:f-”bendl;void main() derived d; d.f(5); /调用derived:f(float) d.f(); /错误,base中的f()被隐藏了虚函数原理? 注意继承类层次中虚函数的位置注意继承类层次中虚函数的位置class Apublic: virtual void f();void g();protected: int a;class B: public Apublic: void f();virtual void g();virtual void h();protect

39、ed: int b;void test1(A& ref)ref.f();ref.g(); /静态联编A:g()type_info_Aint aA:f()vptr_AA的的vtblA对象对象vptr_Atype_info_BB:f()vptr_BB对象对象int aint btype_info_B来自来自A的的vtblB:f()B:g()B的的vtblB:h()多态性的使用? 虚析构函数的作用虚析构函数的作用#includeclass Baseprotected: char* p;public: Base()p=new char5;Base() delete p; cout“Base() fir

40、ed”endl;class Derived: public Baseprivate: char* q;public: Derived()q=new char100;Derived() delete p;cout“Derived fired”endl;void main()Base * p=new Derived;delete p; /调用Base()Derived中中q指向的空间没有释放掉指向的空间没有释放掉将将Derived设为虚析构函数设为虚析构函数virtual Base()多态性的使用? 弹奏不同乐器弹奏不同乐器play(note)InstrumentWindString#includ

41、eenum notemiddleC,Csharp,Cflat;class Instrumentpublic:virtual void play(note)cout“Instrument:play”endl;class Wind: public Instrumentpublic: void play(note)cout“Wind:play”endl; ;class String: public Instrumentpublic: void play(note)cout“String:play”endl; ;void tune(Instrument& i)i.play(middleC);void

42、main()Wind wobj;String sobj;tune(wobj);tune(sobj);多态性的使用? 多态性便于扩展多态性便于扩展class Percussion: public Instrumentpublic: void play(note)cout“Percussion:play”endl; ;class Brass: public Windpublic: void play(note)cout“Brass:play”endl; void tune(Instrument& i)/不变void main()Percussion pobj; tune(pobj);Brass b

43、obj; tune(bobj);play(note)InstrumentWindStringPercussionBrass使用方式:在外部函数中调用虚函数,使用方式:在外部函数中调用虚函数,传入基类引用或指针传入基类引用或指针多态性的使用? 通过指向基类的指针数组记录数据通过指向基类的指针数组记录数据编写同时管理整数和字符串的程序,要求输出这些数据编写同时管理整数和字符串的程序,要求输出这些数据ElementMyIntegerMyStringshowMe()#includeclass Elementpublic: virtual void showMe()=0;class MyInteger:

44、 public Elementprivate: int num;public: MyInteger(int=0);virtual void showMe()cout“MyInteger-”numendl;class MyString: public Elementprivate: char* p;public: MyString(char*=“”);void showMe() cout“MyString-”pendl;void main()Element* list10;/准备list中的数据for(int i=0;ishowMe();多态性的使用? 在在main函数中根据用户选择创建不同类型

45、对象函数中根据用户选择创建不同类型对象#includeclass TradesPersonpublic: virtual void sayHi()cout“Just hi.”endl; ;class Tailor: public TradesPersonpublic: void sayHi()cout“Hi, can I make clothes for you?”endl;class Barber: public TradesPersonpublic: void sayHi()cout“Hi, have you cut hair today?”endl;void main()TradesPe

46、rson* p;int op;do coutop;while(op3);switch(op)case 1: p=new TradesPerson;break;case 2: p=new Tailor; break;case 3: p=new Barber; break;p-sayHi();delete p;多态性的使用? 图形编辑器图形编辑器 - 典型多态使用场合典型多态使用场合class Shapepublic:virtual void draw();virtual bool inShape(int,int);class Line: public Shapepublic:void draw(

47、);bool inShape(int,int);private: int s_x,s_y,e_x,e_y;class Rectangle: public Shapeclass Circle: public Shape设计模式? 设计模式的产生设计模式的产生?复用的重要性复用的重要性?大侠和菜鸟大侠和菜鸟经验值经验值?模式的思想模式的思想?经验如何复用?设计模式经验如何复用?设计模式 or 软件框架软件框架设计模式:将面向对象软件设计的经验记录下来设计模式:将面向对象软件设计的经验记录下来? 设计模式的作用设计模式的作用?使人们可以更简单方便的复用成功的设计和体系结构使人们可以更简单方便的复用成

48、功的设计和体系结构?帮助开发人员做出有利于系统复用的选择帮助开发人员做出有利于系统复用的选择?增加系统的灵活性和可维护性增加系统的灵活性和可维护性设计模式? 设计模式:可复用面向对象软件的基础设计模式:可复用面向对象软件的基础?Design Patterns:Elements of Reusable Object-Oriented software?Erich Gamma等等4人,人,GoF设计模式? 设计模式的定义设计模式的定义?每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次的使用该方案而不必作重复劳动。每一个模式描述了一个在我们周围不断重

49、复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次的使用该方案而不必作重复劳动。(Christopher Alexander)?模式是对反复出现的问题的一种通用解决方案,它是经过实践验证的模式是对反复出现的问题的一种通用解决方案,它是经过实践验证的? 学习设计模式学习设计模式? 设计模式的描述设计模式的描述?名称:助记名名称:助记名?问题:在何时使用该模式问题:在何时使用该模式?解决方案:设计的组成成分,它们之间的相互关系及各自的职责和协作方式解决方案:设计的组成成分,它们之间的相互关系及各自的职责和协作方式?效果:模式应用的效果和使用模式应权衡的问题效果:模式应用的效果和使用模式

50、应权衡的问题设计模式? 设计模式解决设计问题的原则设计模式解决设计问题的原则?寻找合适的对象寻找合适的对象对象根据分析确定,抽象原则对象根据分析确定,抽象原则?确定对象粒度确定对象粒度?指定对象接口指定对象接口针对接口编程针对接口编程?描述对象实现描述对象实现?运用复用机制运用复用机制组合和继承组合和继承?设计应支持变化设计应支持变化问题分离原则、高内聚低耦合问题分离原则、高内聚低耦合? 封装创建对象的过程封装创建对象的过程Factory? 封装特殊的操作封装特殊的操作Command? 封装算法封装算法Strategy? 封装修改动作封装修改动作Adapter设计模式? 继承类层次?多态继承类

51、层次?多态BaseDerived1Derived2Base * p1= new Derived1;Base * p2= new Derived2;类的使用者需要知道子类的名称类的使用者需要知道子类的名称程序的扩展性和维护变得困难程序的扩展性和维护变得困难父类中不知道具体实例化哪一个具体的子类父类中不知道具体实例化哪一个具体的子类ABConcrete1Concrete2(抽象类抽象类)设计模式? 对象创建的过程可能发生变化 ? 封装对象创建的过程可能发生变化 ? 封装? Factory模式模式设计模式? 使得实例化类的工作已到子类中使得实例化类的工作已到子类中? Factory Method模式

52、模式定义一个用于创建对象的接口定义一个用于创建对象的接口(Factory),让子类决定实例化哪一个类。,让子类决定实例化哪一个类。虚构造器:将构造产品类的操作延迟到工厂的子类中虚构造器:将构造产品类的操作延迟到工厂的子类中ApplicationDocument设计模式#includeclass Product public: virtual Product() = 0; protected: Product() ; class ConcreteProduct:public Product public: ConcreteProduct()cout“ConcreteProduct”; Concr

53、eteProduct(); class Factory public: virtual Factory() = 0; virtual Product* CreateProduct() = 0; protected: Factory() ;class ConcreteFactory:public Factory public: ConcreteFactory()coutCreateProductA();cf1-CreateProductB();AbstractFactory* cf2=new ConcreteFactory2();cf2-CreateProductA();cf2-CreatePr

54、oductB();设计模式? 可能遇到接口不一致的情况可能遇到接口不一致的情况驾驶驾驶A不会驾驶不会驾驶Team客户客户B会驾驶会驾驶TeamAB驾驶驾驶TeamAC驾驶驾驶B向向B学习学习设计模式? Adapter适配器模式适配器模式?将一个类的接口转换成客户希望的另外一个接口将一个类的接口转换成客户希望的另外一个接口?使得原本由于接口不兼容而不能一起工作的类能一同工作使得原本由于接口不兼容而不能一起工作的类能一同工作包装器包装器Wrapper类适配器类适配器适用:要使用一个已经存在的类(类库),但其接口不符合需求适用:要使用一个已经存在的类(类库),但其接口不符合需求设计模式class T

55、arget public: Target() virtual void Request(); ; class Adaptee public: Adaptee() void SpecificRequest(); ; class Adapter:public Target,private Adaptee public: Adapter()void Request(); ; #includevoid Target:Request() coutTarget:Request; void Adaptee:SpecificRequest() coutSpecificRequest(); void main(

56、)Target* t=new Adapter;t-Request();设计模式? Adapter适配器模式适配器模式?对象适配器:通过包含已有类来获得服务对象适配器:通过包含已有类来获得服务?适用于无法进行继承的情况适用于无法进行继承的情况(单一继承、源代码限制单一继承、源代码限制)比较:比较:Adapter可以重新定义可以重新定义Adaptee的行为的行为类适配器:类适配器:对象适配器:对象适配器:Adapter可以与多个可以与多个Adaptee一同工作一同工作设计模式#includevoid Target:Request() coutTarget:Requestendl; void Ada

57、ptee:SpecificRequest() coutAdaptee:SpecificRequest_ade = ade; void Adapter:Request() _ade-SpecificRequest(); void main()Adaptee* ade = new Adaptee; Target* adt = new Adapter(ade); adt-Request(); class Target public: Target()virtual void Request(); ; class Adaptee public: Adaptee() void SpecificReque

58、st(); ; class Adapter:public Target public: Adapter(Adaptee* ade); void Request(); private: Adaptee* _ade; ; 设计模式? 可能需要统一处理单个对象和组合对象可能需要统一处理单个对象和组合对象单个图形单个图形: Line、Rectangle组合图形:组合图形:Person单个图形单个图形组合图形组合图形区别对待?区别对待?图形编辑器图形编辑器单个图形单个图形组合图形组合图形设计模式? Graphic基类既代表单个图形,又代表组合图形基类既代表单个图形,又代表组合图形两种图形可以一致对待两种

59、图形可以一致对待设计模式? Composite组合模式组合模式?将对象组合成树形结构以表示将对象组合成树形结构以表示“部分部分-整体整体”的层次结构的层次结构?使得用户对单个对象和组合对象的使用具有一致性使得用户对单个对象和组合对象的使用具有一致性适用:想表示对象的整体适用:想表示对象的整体-部分层次结构部分层次结构希望忽略单个对象和组合对象的不同希望忽略单个对象和组合对象的不同设计模式class Component public: Component(); public: virtual void Operation() = 0; virtual void Add(const Compone

60、nt& ) virtual void Remove(const Component& ) virtual Component* GetChild(int ); ; Component* Component:GetChild(int)return NULL;class Leaf:public Component public: Leaf() void Operation(); ; #includevoid Leaf:Operation()cout“Leaf Operation”endl;设计模式#includeclass Composite:public Component public: Co

61、mposite() public: void Operation(); void Add(Component* com); void Remove(Component* com); Component* GetChild(int index); private: vector comVec; ; void Composite:Operation() vector:iteratorcomIter = comVec.begin(); for (;comIter != comVec.end();comIter+)(*comIter)-Operation(); void Composite:Add(C

62、omponent* com) comVec.push_back(com); void Composite:Remove(Component* com)comVec.erase(&com); Component* Composite:GetChild(int index)return comVecindex; void main()Leaf* lf=new Leaf();lf-Operation();Composite* com=new Composite();com-Add(lf);com-Add(new Leaf();com-Operation();Component* c=com-GetC

63、hild(0);c-Operation();作业?改写改写CardGame类,实现多态调用类,实现多态调用?设计一个类层次,其中的基类为设计一个类层次,其中的基类为Date,它有一个虚函数它有一个虚函数print(输出输出6-22-2004形式形式);从从Date派生派生ShortE类类(print输出输出22-6-2004形式形式)、MediumDate类类(print输出输出Jun. 22,2004) 和和LongDate类类(print输出输出June 22,2004);并且编写并且编写main函数进行测试。函数进行测试。?网络管理软件中,存在抽象基类网络管理软件中,存在抽象基类Host,其中含有纯虚成员函数,其中含有纯虚成员函数poll:virtual HostInfo& poll()=0其中其中HostInfo包含主机的各种信息包含主机的各种信息(ip地址地址/主机类型主机类型/上网时间上网时间/状态等状态等)。从从Host派生出派生出WorkStation、FileServer、PC,每个类都覆盖,每个类都覆盖poll函数,函数,用来返回与派生类相关的信息。编写一个测试程序,其中包含下面的代码用来返回与派生类相关的信息。编写一个测试程序,其中包含下面的代码段:段:for(int i=0;ipoll();

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号