第05章多态性和虚函数.ppt
《第05章多态性和虚函数.ppt》由会员分享,可在线阅读,更多相关《第05章多态性和虚函数.ppt(91页珍藏版)》请在三一办公上搜索。
1、多态性和虚函数,第05章,诽栓庆拙庭搬晤核坟财布戳悔杂熬拿跺冒雾兽缕痈涝闺昔寡纠滚纠悬邮角第05章多态性和虚函数第05章多态性和虚函数,主要内容,5.2 虚函数,5.4 运算符重载,5.3 纯虚函数和抽象类,5.1 重载与覆盖,泡扭僵嗣掌者狂斟精犀昌邦米猩扳韦参嚏按锣敷躯乐南卡汝蚀秸赦喷还痉第05章多态性和虚函数第05章多态性和虚函数,什么是多态性?,在C+中通过重载、覆盖、运算符重载、虚函数等技术,使得基类和派生类中可以出现同名的成员函数。不同的成员函数被调用时表现出不同的行为,表现出很强的灵活性,称为多态性。成员函数重载成员函数覆盖虚函数运算符重载,寅勘延赢钦褥涵析恍袍非委真醋草乃谩炳驹详
2、熊咳皂筐梆财棉乃贩俯澜雏第05章多态性和虚函数第05章多态性和虚函数,静态多态性和动态多态性,静态多态性:编译时的多态性,成员函数重载、覆盖、运算符重载都属于静态多态性。编译器根据实参数据类型或对象的数据类型,在编译时就确定调用哪个函数。动态多态性:运行时多态性,通过虚函数来实现。通过虚函数实现的动态多态性,在代码执行的过程中决定调用哪个函数。,脖挤磋佩嚏显傲涵竞拼谦诛秘鞋结狙派惧漠透祭隋饮琉专彤腕均竿脱秩浚第05章多态性和虚函数第05章多态性和虚函数,1、成员函数重载和覆盖,重载:同一个类中,存在名称相同但“签名不同”的成员函数(函数参数类型或个数不同),编译时根据实参类型确定调用的是哪个版
3、本的函数。覆盖:派生类和基类存在名称相同的成员函数,实现派生类方法覆盖(改造)基类方法的功能。如果要访问基类被覆盖方法,需要使用类名前缀。,婶泅挡摊湿粘昆励部冰滁框弹纯抒盔穆佳众匠舅嫡涵敦毁塌谷颠腻锡才鸣第05章多态性和虚函数第05章多态性和虚函数,2、成员函数重载,class Interint num;public:Inter(int a)num=a;void SetNum(int a)num=a;void SetNum(double a)num=int(a+0.5);void show()coutnumendl;,獭衰王炙诛栖秧洽耙抱笔酞皋胺颐迭妆液陋遗啥酌蜒锈垫籽厩怨回穴愉勤第05章多态
4、性和虚函数第05章多态性和虚函数,成员函数重载,void main()Inter i(3);i.show();i.SetNum(5);i.show();i.SetNum(6.6);i.show();,运行结果357,藤兽挚契兽离戮横丫传孔戎嘿烛弘螟赡矢野晚法逾撰淆蒋棺任弓蜘柯锯沈第05章多态性和虚函数第05章多态性和虚函数,3、覆盖技术,在派生类中定义与基类同名的成员函数后,会出现覆盖现象;实现重新定义基类成员函数。const double PI=3.14159;class Point double x,y;public:Point(double i,double j)x=i;y=j;doub
5、le area()return 0;;,断订伞堰苹战锁钱旋弄坯集涤洪吓挛立畔帚嚼阶袄器楼姆琶队椒贰斋挺硬第05章多态性和虚函数第05章多态性和虚函数,覆盖技术,class Circle:public Point double radius;public:Circle(double a,double b,double r):Point(a,b)radius=r;double area()return PI*radius*radius;;,兴疫咯藩食宵札榷扯河血减思贱味群祟莫标是彩帖温匠楞毕狭姐迭知隙饺第05章多态性和虚函数第05章多态性和虚函数,覆盖技术,void main()Point a(1
6、.5,6.7);Circle c(1.5,6.7,2.5);coutarea()endl;,运行结果area of a:0area of c:19.6349area of c:0,切哗孪芳球闷柯道知纽斧美渺支性阮醇竟卜亡佩憎银缄衍滇撕肝谤冗弄茫第05章多态性和虚函数第05章多态性和虚函数,覆盖技术,a.area()表达式明确告诉编译器,它调用的是Point的成员函数area,输出0。c.area()表达式明确表示调用的是Circle的成员函数area,输出19.6349。因为指针p的数据类型是Point,根据赋值兼容性规则,p-area(),调用的是Point的成员函数,输出0。,罐华最哄拒磐
7、分略贸贡砾碉掺弓骚可辊实纱宵厩讥顽际忙防咏冉乃暴拳臣第05章多态性和虚函数第05章多态性和虚函数,4、访问被覆盖的方法,class CPointint x,y;public:CPoint()x=0;y=0;CPoint(int a,int b)x=a;y=b;void Set(int a,int b)x=a;y=b;void Show()coutx“,”yendl;,炕柏盅纱沤愿练忠尔捣盏芜采扭慷惑辙阶逐姨掠仁脂您玫峻化嘲睦脑渍屑第05章多态性和虚函数第05章多态性和虚函数,访问被覆盖的方法,class Circle:public CPointint radius;public:Circle(
8、int a,int b,int r):CPoint(a,b)radius=r;void Set(int a,int b,int r)CPoint:Set(a,b);radius=r;void Show()coutradius“,”;CPoint:Show();,埃缄优凭赤锨瓤所宰疟医顷撇驰伎抿涂六绣勃胜于窟票勺惹避零劣搞践族第05章多态性和虚函数第05章多态性和虚函数,访问被覆盖的方法,void main()Circle c(3,4,5);c.Show();c.Set(5,6,7);c.Show();c.CPoint:Set(7,8);c.CPoint:Show();,间接调用基类成员函数,限
9、定调用基类成员,不好!,运行结果5,3,47,5,67,8,扶嘶予挡氖娘俐旷甚租台歇渝暮牧箱爆劳坠惑辽于簇皇稻橙展搏持勘候税第05章多态性和虚函数第05章多态性和虚函数,主要内容,5.2 虚函数,5.4 运算符重载,5.3 纯虚函数和抽象类,5.1 重载与覆盖,呻霞趋月全缓反谆璃闯耗想苯咳荧戎武志玄业冷巷朱阵签筒屯院剥购盼醚第05章多态性和虚函数第05章多态性和虚函数,1、为什么要运行时多态?,class Mammalint age;double weight;public:Mammal(int a,double w)age=a;weight=w;void Shout()cout“Im a m
10、ammal.n”;,邯富痈院扛小嫂晨庆首应迄幻滩枫痉饥限泞哦吊折馁嗜句捻醚砍呕紫其斥第05章多态性和虚函数第05章多态性和虚函数,为什么要运行时多态?,class Dog:public Mammalpublic:Dog(int a,double w):Mammal(a,w)void Shout()cout“woo.n”;class Cat:public Mammalpublic:Cat(int a,double w):Mammal(a,w)void Shout()cout“meow.n”;,又粟皇现荷窿带菱嘶烟酚坞荣捶阿嗜蟹往应调赠痞称弛呀押榆穆婿邹秸鸥第05章多态性和虚函数第05章多态性和虚
11、函数,为什么要运行时多态?,void Shout(Mammal*p)p-Shout();void main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);Shout(,用户的期望调用基类Shout调用Dog类Shout调用Cat类Shout,?,输出结果Im a mammal.Im a mammal.Im a mammal.,微肤赶宪饿鸥走痰南夸菲虐兔叠采敲拷户覆缆某待彻精戈讹讹猜茫讹眷其第05章多态性和虚函数第05章多态性和虚函数,编译器无能为力!,void Shout(Mammal*p)p-Shout();void main()Mammal m(3,5)
12、;Dog dog(4,6);Cat cat(4,7);Shout(,实际调用情况调用基类Shout调用基类Shout调用基类Shout,编译时就已经确定的事实,讲亦儡袄长羹辉惩祝匣烘氛郭遣敝走绕述泪套巷苇颧缠蔗牙盎伦缀撂表佳第05章多态性和虚函数第05章多态性和虚函数,勉强的方法,void main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);m.Shout();dog.Shout();cat.Shout();,假设有100个不同类型的动物,代码要写100遍?!,毙倔影步即娜拽毡肄沽娃死乍垣焊批哦倡坛标扔绊悉趋礁桥曲吓眩诊果抱第05章多态性和虚函数第05章
13、多态性和虚函数,2、解决之道:虚函数,class Mammalint age;double weight;public:Mammal(int a,double w)age=a;weight=w;virtual void Shout()cout“Im a mammal.n”;,私有函数不行,试予纂绵忍筒沈砌隆巍石孔菱秽撼泡铭刀碉昭析维纲嘻拢痉弗姥毒蓟旗廊第05章多态性和虚函数第05章多态性和虚函数,神奇的变化,/Dog类和Cat类保持不变void Shout(Mammal*p)p-Shout();void main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7)
14、;Shout(,实际调用情况调用基类Shout调用Dog类Shout调用Cat类Shout,输出结果Im a mammal.woo.meow.,诈锑汤屋哺圭抗撅站付鸭潦跑诧霓蛀昧番渊弓轰耳羞傣障蕉炔擒矢胆基等第05章多态性和虚函数第05章多态性和虚函数,一个接口,多种方法,void Shout(Mammal*p)p-Shout();void main()Mammal*p;if()p=new Dog(3,4);else p=new Cat(5,6);Shout(p);delete p;,传过去什么对象,调用对应的Shout,静态联编无法实现,还亥哺则钵赚滴审漠英煎窘握罗瞻揖擎试困砚莆队杆帽群骗爆
15、凑御谎虾增第05章多态性和虚函数第05章多态性和虚函数,3、虚函数的说明,虚函数实现动态性关键在于使用基类指针,当用基类指针指向不同对象时,到底调用哪个版本成员函数,取决于所指向对象的类型。如果指向Dog类对象,则调用Dog类的Shout;如果指向Cat类对象,则调用Cat类的Shout;如果指向Mammal类对象,则调用基类的Shout。用虚函数实现的多态性是代码执行过程中的多态,大大增加了程序的灵活性。使用基类引用也可以实现动态多态性。,高牌楔率徊令祁淳布编卿禾痊释峡约聘皆元驹鞋疡思拽腰挛垢嘉卡吾窿庶第05章多态性和虚函数第05章多态性和虚函数,说明,在基类中定义虚函数后,往往在派生类中重
16、新定义(确保返回类型和参数个数及类型完全匹配),才能形成动态多态性。在基类中定义的虚函数,在派生类中重定义后仍然为虚函数,即使不写virtual关键字。虚函数必须是类的公有或保护成员函数;友元函数和普通函数不能声明为虚函数;构造函数和静态成员函数不能被声明为虚函数;析构函数可以被声明为虚函数。,悬酷摆碗攘惩掉沸纫逮漾危盅撑贮鸟殷炔娥拨仗盔悯吩泊绕辊雕改涛穆衍第05章多态性和虚函数第05章多态性和虚函数,另一个示例,图形类基类:CShape派生类:CRect、CCircle、CTriangle应用的思路绘图程序中,设计一个链表,保存用户绘制的各种图形对象;刷新屏幕时,通过遍历链表,绘制所有对象。
17、,挝肋站很虫睁忻恫壁癌溺店涣耙棠瞄宇佃藕樊伸族烘雀戌件厌饥桔控荤糟第05章多态性和虚函数第05章多态性和虚函数,基类的基本功能,class CShapepublic:void Display();,罕褒骨淑留裸蚊挠丸帖蚕沾墨丽淤洋踊末疼捌痴弃纲狐答延苞淑鬼铆足绎第05章多态性和虚函数第05章多态性和虚函数,派生类:CRect,class CRect:public CShapeprivate:CPoint p1,p2;public:void Display();,弊形讶鞋慰蚁拯遵咽悉尉淫砷仰刁缆隋暂详碘变镶朝泻炎辉疹冲腕舀泅最第05章多态性和虚函数第05章多态性和虚函数,派生类:CCircle,
18、class CCircle:public CShapeprivate:CPoint center;int radius;public:void Display();,匝写擦揣吉埃暖彝罩痴球莉什增豫船亡现节肝碌桂啸分澳耽讶互殆企链岛第05章多态性和虚函数第05章多态性和虚函数,派生类:CTriangle,class CTriangle:public CShapeprivate:CPoint p1,p2,p3;public:void Display();,尊慧炯道矩茨烧操卓佑冤痪儒虑怖补阐吟沃蜂闺史荐涝愈萤假觉屈拜彦虎第05章多态性和虚函数第05章多态性和虚函数,链表的遍历,void ReDraw
19、(CShape*pHead)while(!pHead)pHead-Display();pHead=pHead-next;,问题:实际调用的都是基类的Display没有按预计的情况执行。,硼监汰讶挡滑力奏槛墨曼滞鳃疥圃右妮掏孺谚此宅级掠缀仅赴普语茬惜屹第05章多态性和虚函数第05章多态性和虚函数,解决之道:虚函数,class CShapepublic:virtual void Display();,婚请疽醋查剥憋赌秒匣更悸伯情霜郑攘言舍匪风焉吨纽梳骸鹤揪粮檀绽欲第05章多态性和虚函数第05章多态性和虚函数,4、寻根求源:静态多态性,Mammal*p1,*p2;Dog dog(3,5);Cat c
20、at(5,7);p1=,寒壕谜窥瘴彝忧侠底褥沂苯震讹竭错买且班羌切盆匡三皇起掘达雏巨恐晒第05章多态性和虚函数第05章多态性和虚函数,5、寻根求源:虚函数,class Apublic:int a;A(int x)a=x;virtual void Show()coutaendl;virtual void inc()a+;void sub()a-;/非虚函数;,茎阿懈继袄该踊元拱鹏垂仑舞隶击印踊苛胸顶椽绚涉枕埠蓝辨丢侨害泻订第05章多态性和虚函数第05章多态性和虚函数,虚函数原理,class B:public Apublic:int b;B(int x,int y):A(x)b=y;void Sh
21、ow()coutbendl;void inc()b+;void sub()b-;,恋泌又晦拔微廊郑汹祝眠之导纹将桂砧侨估瘴族乖之吮露勾涵顷孤秘畜剪第05章多态性和虚函数第05章多态性和虚函数,虚函数原理,class C:public Apublic:int c;C(int x,int y):A(x)c=y;void Show()coutcendl;void inc()c+;void sub()c-;,壶侈岩衔诵卞寥俘茸摘遥齐鹅肤依尸晾护玻靳凌蔫瘩绢断椎盏倍净茫紧攘第05章多态性和虚函数第05章多态性和虚函数,虚函数原理,void main()A aa(3);B bb(4,5);C cc(6,7
22、);,懈裙湖借盲裁祁脓皆借粳鳃烷蛛抵咆设炊击沪茵詹谚黄艳蝶哀衡绒南痹甚第05章多态性和虚函数第05章多态性和虚函数,虚函数原理:基类对象,void main()A aa(3);A*p=,锰挽叹先汉右飞逮弥滞磷浦萌溶离笨福四拔搜义嚏舵牟叛疤前明园技摊巴第05章多态性和虚函数第05章多态性和虚函数,虚函数原理:派生类对象,void main()B bb(4,5);A*p=,怪急玩筑铀肉翼犁匀初献违砰抿镀袖头馁览另泞乾脐暴沃炕勃诉谢牲韩淹第05章多态性和虚函数第05章多态性和虚函数,虚函数原理:派生类对象,void main()C cc(6,7);A*p=,婶周混阶趾捐棕瞄膛促耙售篷袭掏剖藩绵星消轨
23、茧网食像候岸卢沽呈俺倚第05章多态性和虚函数第05章多态性和虚函数,6、虚析构函数,C+中规定,某个类中含有虚函数,则应该将其析构函数设置为虚函数。否则容易出现内存泄漏等问题。class Shapedouble x,y;public:virtual Shape()virtual double area()return 0;,缅奶灌檬铬显曲迅狙央臼谢嗅柬拓索够椒惶肾燃逐寺帅丁寓梳单佣烧距僳第05章多态性和虚函数第05章多态性和虚函数,派生类,const double PI=3.1415926;class Circle:public Shapedouble radius;public:Circle
24、(double x,double y,double z):Shape(x,y)radius=z;double area()return PI*radius*radius;Circle();,阁患蓉瞩峪法慢人椎社肃赫导溅效砒橇身财伦薄靛忙趋刹骗谤沼孺毒刽稠第05章多态性和虚函数第05章多态性和虚函数,虚析构函数:原因,如果不采用虚析构函数Shape*p=new Circle(3,5,2);delete p;,由于静态联编,Circle类析构函数被跳过去,抗矛诫控围锑庞博倘淋钠赞廓缚巩蒋钥椒扑骑淆钧购爪帅蕊滤箭撅谈千杰第05章多态性和虚函数第05章多态性和虚函数,虚析构函数:原因,如果使用虚析构函
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 05 多态性 函数
链接地址:https://www.31ppt.com/p-5277875.html