《要素类和对象模版类的继承》由会员分享,可在线阅读,更多相关《要素类和对象模版类的继承(159页珍藏版)》请在金锄头文库上搜索。
1、n nC+要素n n类和对象n n模版n n类的继承铅同摧钓至蹦畅颓恕孕蘸由颤男谐瘸锤界哄拣猾赘枯彤金幅邯叹方碑帝寸要素类和对象模版类的继承要素类和对象模版类的继承C复习数据类型数据类型:在:在C语言中语言中:基本类型和构造类型基本类型和构造类型基本类型:整型、浮点型、字符型、基本类型:整型、浮点型、字符型、双精度型双精度型 构造类型:数组、结构、联合、指针、枚举型构造类型:数组、结构、联合、指针、枚举型数据对象数据对象:intn=3;inta3;a0=-1;/整型数据对象整型数据对象charch=A;/字符类型数据对象字符类型数据对象对象指针对象指针:int*p=&n,*q=a;宛猴吸蝶甩革
2、悔鄙孤尔斑闸泞躯税踢岸挠眶柯说撼芋爸黑躁庐通愿兼啦谎要素类和对象模版类的继承要素类和对象模版类的继承C复习标识符表达式语句:赋值句、条件句、循环句、函数调用(输入输出)函数:返回值类型,函数名,参数列表递归:直接递归、间接递归驹笑逞猜猪弘犁缔住抬瑚蛤檬森禽盅斟蚜阐苗圃休御石崔团玫荷禁戚喻慰要素类和对象模版类的继承要素类和对象模版类的继承C+介绍一一.C+C+要素要素 (BorlandC,VC)溢亦噪牵批你凑滓瓮谤又卞缕蔼里臆舷犀楚箍蹭乙淘介帧胰灶粱铜秆舷肉要素类和对象模版类的继承要素类和对象模版类的继承*.cpp注意:C+源文件扩展名用.cppC源文件扩展名用.c1.文件扩展名丑在悟玛光硬滔镑
3、卜雌质望惭葵襄耪嘲令射矮农反辗嵌椿猎镜洼蝶鸥滦淄要素类和对象模版类的继承要素类和对象模版类的继承/*/段注释以/*开始到*/结束/行注释到行末2.注释悼吃渤涣涪殷貉邦毡倚弧敷岭肃惰丧翅槽担饿转悸掘寇珍技晌府档垂嫩短要素类和对象模版类的继承要素类和对象模版类的继承例1:constintm=10;/定义m为常量值是104.常量说明const例2:constinta=1,3,5,7,9;/定义a是常量数组例3.int*constp;/常指针p指向一个固定的地址例4.constint*q;/指针q指向常量卷现缕述谤谋祟恼昆趟亮口瞒螟怎棵振籽愁吩鼻烩芝驴陶姨愉阿辣从枣砖要素类和对象模版类的继承要素类和对
4、象模版类的继承可以在任何地方申明一个变量例for(inti=0;i5;i+)其作用域从申明地起到文末或函数末5.变量申明但不能while(inti)i+;漂诡邀米冶坤测汕炉沽兵麓腰钓梯山莱奠休面澈清箭皱裴宠霓槽耍醉阎叶要素类和对象模版类的继承要素类和对象模版类的继承intf(inta,intb=0);调用f(5),即调用f(5,0);6.函数缺省值参数缺省参数要写在参数表的右边intf(inta,intb=0,intc=1);弄沈棚软饰洪芥玉扒浚企翔狄撮售孕缆返僵封彻常炕机淡讶凤蔬俭廷田顶要素类和对象模版类的继承要素类和对象模版类的继承inlineintsquare(intx)returnx*
5、x;内联函数先编译,效率高,速度快但只能有四五个语句,不能有循环语句,条件语句.7.内联函数畦军凄镊贯战翔抉拱梢衔贾搜酝警指偿论跃刻萨沸勇佑尿险份憨陵互韦脓要素类和对象模版类的继承要素类和对象模版类的继承overloadabs;intabs(int);floatabs(float);同名不同参数的函数可以重载系统会自动选择调用8.函数重载题告肩征尾责豁死赡窒厩蔡厦翻绷俗凯铣动圭镇稀腿雄殆琅播私社柱齐尤要素类和对象模版类的继承要素类和对象模版类的继承定义函数的变量参数例intf(int&x)intn=2*x+;returnn;x为函数f的变量参数调用实参的地址调用后实参的值可以改变函数需要两个以
6、上返回值时,用变量参数9.引用操作符&美炉跋吠档菩圈吐普暴站睦廖破坊樊茁钠州融矽桂貌俗百俊戊帽鞋逃贞或要素类和对象模版类的继承要素类和对象模版类的继承例int*p,*q;p=newint(3);q=newint4;为p分配一个整形地址(2字节)*p=3为q分配4个整形地址(8个连续字节)deletep;/撤销p的地址deleteq;/撤销q的多个连续地址10.动态函数动态变量newdelete鼻哦趴亏稚浸厕压宵控员勘恿丘乍数誓楔侍扁柑崩挛窗惶望库竹甭匠陀罪要素类和对象模版类的继承要素类和对象模版类的继承#include“iostream.h”inta,b;charx,y;cout“Enterx
7、,y,a,b”xy;从键盘为变量x,y输入数据cinab;从键盘为变量a,b输入数据cout“x=”xendl;coutyabendl;11.输入输出瘟解谚壤锗臼单糖骨仆姐曲历布叼轴掳黔登佳移颁窖忘渗掷盅匹闻货探俯要素类和对象模版类的继承要素类和对象模版类的继承文件输入输出include“fstream.h”include“stdlib.h”voidmain()ifstreaminfile(“datafile1.doc”);if(!infile)cerr“Cannotopendatafile1.doc”endl;exit(1);ofstreamoutfile(“datafile2.doc”);
8、if(!outfile)cerr“Cannotopendatafile2.doc”n)infilename;outfilen“”name0)value=x;elsevalue=0;/有参构造函数voidincrement()if(value0)value-;unsignedaccess_value()returnvalue;怖陕庶孔畴氧础筑靠抬味詹倒刑奔唁清侈账还绝协住铆且买骆撅克骨恩烹要素类和对象模版类的继承要素类和对象模版类的继承counterc1,c2;/语句1counterc3(5);/语句2语句1定义counter类的对象c1,c2,即实际变量(实例)。对象定义时必须为数据成员赋初值
9、即初始化。初始化由类中的构造函数自动完成。语句1自动调用counter类中无参构造函数,使c1.value=c2.value=0。语句2定义对象c3,自动调用有参构造函数使c3.value=5.2.对象的定义object斋寂战铲笔田李番梧右腰桂扛幌刽乘浚肤拴富乱眩毖林邯上薄贮姨班闭坍要素类和对象模版类的继承要素类和对象模版类的继承注意:不能使用c1.value为它赋值;因为value在counter类中是私有成员不可见,只能用成员函数来调用。对象不能直接调用私有成员,只能通过公有成员函数来调用私有成员对象调用成员函数,叫发一个消息为c1发消息:c1.increment();/计数器自动加1c1
10、.decrement();/计数器自动减1靖撩山拎沦簿档序秀弓嘿琅炒胺骋滚锈孰拨喳竖笆州演莎铱阶予薛簧怀蛆要素类和对象模版类的继承要素类和对象模版类的继承例计数器测试程序#include“iostream.h”#include“count.h”voidmain()counterc1,c2;for(inti=1;i=8;i+)c1.increment();cout“nc1=”c1.access_value();c2.increment();cout“c2=”c2.access_value();for(i=1;i=5;i+)c2.decrement();cout“nc2=”c2.access_va
11、lue();c1.decrement();cout“c1=”c1.access_value();井蒙脾翔虾陆屈辽灸区树欠婿帧挝送鲸稠登耻惊纽簇否沈出冗簧乒赊标谆要素类和对象模版类的继承要素类和对象模版类的继承测试结果c1=1c1=2c1=3c1=4c1=5c1=6c1=7c1=8c2=8c2=7c2=6c2=5c2=4c2=3c1=3驱招于机机浦垦吹酞觉篱意线呼鲜侵捶颅舍祝乾赊炽堡灯争廓宇锤痰九娥要素类和对象模版类的继承要素类和对象模版类的继承圆的类classCirclefloatradius;public:Circle(floatr=0):radius(r)/构造函数floatGetRadi
12、us();floatCircleCircum();floatCircleArea();尽炉饼扦盗蓟档签纱文霓丁睫捌卒什株哗贵桩阳效腺缩售钱呻姐阉衅直材要素类和对象模版类的继承要素类和对象模版类的继承成员函数类外定义Circle:Circle(floatr)/构造函数radius=r;floatCircle:GetRadius()returnradius;floatCircle:CircleCircum()return2*3.14.6*radius;floatCircle:CircleArea()return3.1416*radius*radius;谁铰孕宴纲欺血圭赚吐兑虐仑弘操份猩枯壕篆橡栅广
13、益甫鲤零腐钳钥氦僳要素类和对象模版类的继承要素类和对象模版类的继承圆类的测试#include“iostream.h”#include“circle.h”voidmain()Circlea(3),b(2);cout“CircumofCirclea=”a.CircleCircum()endl;cout“AreaofCircleb=”b.CircleArea()endl;丽锨套棉蒂平茄甄脱脾妨斧阜搏擂渔督壤运陛氰孙调僻汞擎逻哩酸竿拿刮要素类和对象模版类的继承要素类和对象模版类的继承长方形类classRectanglefloatx,y;public:Rectangle(floata=0,floatb=
14、0):x(a),y(b)floatRecCircum()return2*(x+y);floatRecArea()returnx*y;田导淤鸦螟寥赡谆塔庸帛盒矣傻赫吹拇唇瞎粉季河耿辆迢弦曼勒欺缆舟兵要素类和对象模版类的继承要素类和对象模版类的继承a.对象指针如同定义一个对象一样,用类名可以申明一个对象指针。例counter*p,*q;申明counter类的指针,指针没有初始化,调用指针必须先分配内存,或指向一个变量的地址,否则出严重错误,甚至死机。3.对象指针和对象数组对象指针和对象数组写陨横娜泄昼渔厚纯牧钨陀险桶杨梳豢蹋逮并棵檀斑暑街管翅兜侣赦樟渠要素类和对象模版类的继承要素类和对象模版类的继
15、承(1)p=newcounter(3);分配一个整形数据内存,这时系统自动调用有参构造函数初始化*p的value=3;(2)q=newcounter3;分配三个连续整形数据内存,这时系统自动调用无参构造函数初始化q,q+1,q+2的value都是0。如果类中没有无参构造函数,语句(2)出错。枪轮案瞳盒制佑默增泻牵秦断畦矫菠香辱珐歇循矩烷进岩悉啪乐鼠姥它熙要素类和对象模版类的继承要素类和对象模版类的继承确定地址后的对象指针可以调用类中公有数据及公有函数。pincrement();(q+1)decrement();(*p).decrement();(*p).decrement()中的括号不能省略,
16、因为运算符.的优先级高于*;对象指针用毕,要予以撤销,释放内存,deletep;deleteq;撤销后的指针可以再用,只要重新分配内存或指向一个内存。瘤炔澡枕淬了省遗遁灶疲奈互尘驶莉就殿懂癌屈疹尹赃埃饯铲饺垃泽授殿要素类和对象模版类的继承要素类和对象模版类的继承b.对象数组如果类中有无参构造函数,可以定义对象数组(3)counterc3;这时系统自动调用无参构造函数初始化c0,c1,c2的value都是0。如果类中没有无参构造函数,语句(3)出错。恢巢窑袱深官翅染等晦漳腥靛坤宫例勋沤渝旋暇蓝体间呢透枷遇梧爆炔闲要素类和对象模版类的继承要素类和对象模版类的继承a.一个类中的数据成员不可以初始化,
17、例classAintvalue=0;出错.;b.另一个类的对象可以做本类的数据成员,但要先定义后作成员。只先申明不行。本类对象不可以做自己的数据成员。c.指向本类或另一类对象的指针,或引用可以作本类的数据成员。只要先申明就可以。4.类的数据成员类的数据成员婪锡到疗染役肿巳棱霓勘柿观糯酸沮孽型至频读绳晒詹周眺十刀巧我味枉要素类和对象模版类的继承要素类和对象模版类的继承d.公有成员和私有成员的先后次序可以交换。可以把私有成员写在类的前部,也可以写在后部。e.本类对象可以调用本类公有数据或公有函数,不能调用私有数据和私有成员。址揣味娄到模培帖肆攻质漳呜右钎馒蠕逼厄羚哆厦瑟缩剃讶纵中诲及进篓要素类和对
18、象模版类的继承要素类和对象模版类的继承例classA;classBA*p;/合法A&q;/合法B*r;/合法Aa;/出错Bb;/出错;炎李删许晕咏首瓦誉徐袱争我橙坪婪蜂纽梭呵郑男线忆踪豪颠屿商勃概很要素类和对象模版类的继承要素类和对象模版类的继承长方形和圆的类classRecCircleRectangleRec;CircleCir;public:RecCircle(floata,floatb,floatc):Rec(a,b),Cir(c)floatCircum()returnRec.RecCircum()+Cir.CircleCircum();floatArea()returnRec.RecA
19、rea()+Cir.CircleArea();草殆侧注唐驯纳旦四柳皑匆唁蓝邪纷象怜砌示使儒砚淮箭溜挚叁抛蠢虹刚要素类和对象模版类的继承要素类和对象模版类的继承成员函数也叫类所具有的方法或操作。函数头叫方法的界面,也叫消息模式。函数可以重载(要求参数不同)不必用overload。可以类内申明类外定义,类内定义时不用inline即内联。成员函数可以调用本类数据成员,无论公有或私有。对象调用公有成员函数叫做发一个消息。5.类的类的成员函数成员函数父枯剥盆态虹履汰恋灶兔伤菏赛欣蝉宝抛驾咐逻达搀暖欲婴遗酗腮恐菊峙要素类和对象模版类的继承要素类和对象模版类的继承构造函数可以重载,带缺省参数时,要特别注意避
20、免二义性。构造函数一般都是公有函数。只有私有构造函数的类不能定义对象。只有本类对象或本类成员函数才能调用成员函数。裁唐椰鸯爸鲸闺滥酝答立厕贯致很瞩体吾冬昏氮被板穷拧术陋榨讥栋锻拍要素类和对象模版类的继承要素类和对象模版类的继承成员函数必须由对象调用,调用成员函数的对象可以看作一个隐含的参数,这是一个指针参数,用this表示。this指针指向调用成员函数的对象。例Circle:CircleArea()return3.1416*radius*radius;/其中radius实际意义是thisradius.Circlea(3.4);couta.CircleArea();/this指针指向a6.Thi
21、s指针指针韧狙变戈读塘族裳抄懈拽邻箱经汁沁呸试晶蓄向太口苍儡玻式坑辫途建肖要素类和对象模版类的继承要素类和对象模版类的继承this指针counter:increament()if(valuevaluecounterc;c.increament();/实际参数是c,this指向c庭峡唱盯烬莲嚼副深屠仓案涵馁较娩侧玖墟两氓诉鸦封耪室轿装庇阐窃孙要素类和对象模版类的继承要素类和对象模版类的继承与类名同名的成员函数叫构造函数,构造函数没有返回类型。构造函数的作用是自动为对象初始化。对象不能调用构造函数。如果一个类中没有构造函数,系统会自动生成一个无参构造函数。如果一个类中有有参构造函数,系统就不再自动
22、生成无参构造函数,这时,用类定义对象数组或对象指针都可能出错。7.构造函数构造函数腻策最决旧摇永傈疹查漾咀瞬缓饰跳抉冬挂踢歌恩牲汇旦拌闽罢就株迁刽要素类和对象模版类的继承要素类和对象模版类的继承一个类中如果没有构造函数,系统会自动生成一个无参构造函数,使所有的数据成员都置0。一个类中如果有有参构造函数,系统就不再生成无参构造函数。例如RecCirle类中,就没有无参构造函数。这时要小心,下面一个语句会出错RecCircled;/出错无法初始化RecCircles3;/出错无法初始化正确的定义形式是RecCircled(2.0,3.5,4);眺散坊腿磁僻纤珍迂底满撂奄舞气超暮搞胶篷劫湿靳析鸥育洲
23、灵帽蹲凝冶要素类和对象模版类的继承要素类和对象模版类的继承懈揉聊蒲伸曝各库祝尤楚坝涝燎渣赶药湘僻吃俱憎小沂萌冰壬邦功后瞻寝要素类和对象模版类的继承要素类和对象模版类的继承8.拷贝构造函数拷贝构造函数构造函数的参数不能是本类对象,但可以是本类对象的引用,这样的构造函数叫拷贝构造函数。凰埔悍扣埠柜焕傣佯菇豹厄焉汞殆铰臀恤扛始液脏雷卯补梧沃党会隧岸默要素类和对象模版类的继承要素类和对象模版类的继承classCirclefloatradius;public:Circle(floatr=0):radius(r)/构造函数Circle(Circle&c)radius=c.radius;/拷贝构造函数flo
24、atGetRadius();floatCircleCircum();floatCircleArea();阵挫哦抛辐灵废凉吱仇愤潜节肉起卉戊驮锣阮捅妙疵半股吟掂蘸胡瞒阮傲要素类和对象模版类的继承要素类和对象模版类的继承1)用已有对象定义新的对象。Circlea(2);Circleb(a);第二个语句就是利用拷贝构造函数定义赋数对象b,b的半径等于a的半径。拷贝构造函数的作用:身澳汪谢潞储烽颤软颅琢茅彝恍糕铬董方拒甭勺买器诚游检眶净槛暮燃查要素类和对象模版类的继承要素类和对象模版类的继承拷贝构造函数的作用:2)本类对象作函数的参数时,要用拷贝构造函数传值。3)一个函数的返回值是本类对象时,要用拷贝
25、构造函数赋值。CircleFun(Circlet)returnCircl(2*t.radius);泊谣晴赛为钠咱批筷儒科藕熙浊甸屠尼辛播辕伊被奎锯空语死窟素烩伪选要素类和对象模版类的继承要素类和对象模版类的继承如果类中没有拷贝构造函数系统会自动生成一个。如果类中有指针成员,就必须专门定义拷贝构造函数,否则可能出错。景佣胁永姨窑靖与偶敝阴时籍释未酷模缘抄掖手值吕簧涛锻岛邓匿脏那七要素类和对象模版类的继承要素类和对象模版类的继承例classAint*p;pubic:A()p=newint(0);A(A&s)p=newint(*s.p);脖帕洁唐里咏丈他叶匣谗贫犹嗣赋斯谆督轩常舞步款末胞屑苫券冉买致
26、返要素类和对象模版类的继承要素类和对象模版类的继承以开头与类名同名的成员函数称为析构函数。析构函数无参无返回值。例classA.A();.;9.析构函数弟架黄恩电募腋姚遮靖厩射塔讼枚睬秋剁捏汹硝遏慰幻缕悦傍焰渍栈踢刘要素类和对象模版类的继承要素类和对象模版类的继承析构函数的作用:当本类的一个对象用完后,系统自动调用析构函数,撤销内存。这种情况常在一个函数中发生,一个对象在函数中作局部变元,函数用毕后,局部变元失效,析构函数就会自动起作用。类中没有析构函数时系统会自动生成一个析构函数。当类中含有指针对象时,应当定义一个析构函数,以免指针指向的内存挂起失。霜挞倡脓绣峦圭彰司报尖擂浊枉找原赂忿然涣茵
27、坪履酶芍瞧嚷渠甩鞭聚祷要素类和对象模版类的继承要素类和对象模版类的继承classAint*p;public:A()p=newint;.A()deletep;.;注意类外对象指针用new分配的内存,不会调用析构函数,而要用delete释放。芽剥偶稳扁固诞汾障郝招莫蚀终观状毯怜疚搪邪绝惮艺胰舔娟娇婿搅匠肚要素类和对象模版类的继承要素类和对象模版类的继承例坐标点point类classPointpublic:Point(int,int);/构造函数Point(Point&);/拷贝构造函数/Point();析构函数intget_x();/取横坐标intget_y();/取纵坐标Pointoperato
28、r+(Point&);/重载+Pointoperator*(int);/重载*獭务踏顾削砰底钟角祟袁银斋教睹臂柞宫尽茵饭成棺贩侦昨牧呢殿肇碎既要素类和对象模版类的继承要素类和对象模版类的继承Pointoperator-();/一元函数重载Point&operator=(constPoint&);/赋值函数private:/私有数据intx,y;friendistream&operator(istream&,Point&);/友元输入函数重载friendostream&operator(ostream&,Point&);/友元输出函数重载(istream&istr,Point&p)istrp.x
29、p.y;returnistr;ostream&operator(ostream&ostr,Point&p)ostr“(”p.x“,”p.y“)”(istream&istr,Point&p)istrp.xp.y;returnistr;ostream&operator(ostream&ostr,Point&p)ostr“(”p.x“,”p.y“)”endl;returnostr;友元不是类的成员,不用类名域Point:operator甫躬厚皱集爸辜夺猾申裁聋颤爵矗讥七详匙啃翅悠刁拖崭格螺酿群被莽燃要素类和对象模版类的继承要素类和对象模版类的继承函数在类内申明类外定义函数在类内申明类外定义例例日期类
30、日期类保存于保存于“date.h”中中classdateintmonth,day,year;/私有数据public:date(int,int,int);/有参构造函数voidnext();voidprint();today;腰爸呐卿坍四盲斜跪烛刑趋爹俄奴阿藏瓢野仔饰道之咀买槽寸履卡林龟囤要素类和对象模版类的继承要素类和对象模版类的继承inlinedate:date(inta,intb,intc)month=a;day=b;year=c;voiddate:print()coutmonth“/”day;cout“/”yearendl;颠荐棉姬胰咐礁帧亲具才钥床坞蜕简佳富咽措讫外怒碑瓷综佬奇锡霞友际
31、要素类和对象模版类的继承要素类和对象模版类的继承voiddate:next()switchmonthcase1:case3:case5:case7:case8:case10:if(day31)day+;elsemonth+;day=1;break;case4:case6:case9:case11:if(day30)day+;elsemonth+;day=1;break;case12:if(day31)day+;elseyear+;month=1;day=1;break;case2:戳绊贬董轮揣纱淆弟司赁另痔鸟熟驭式浅捶成吼否牢痴缝陡选八哟炎毒眠要素类和对象模版类的继承要素类和对象模版类的继承c
32、ase2:if(year%4=0)&year%400!=0)|(year%400=0)if(day29)day+;elsemonth+;day=1;elseif(dayb?a:b;floatmax(floata,floatb)returnab?a:b;charmax(chara,charb)returnab?a:b;可以统一写成一个模版函数咙绕揍眉盯熙夫彬浆孺惠充韩父恢挠饺槐陷煮泰压次粤阻柯罚汝郁刁姆摆要素类和对象模版类的继承要素类和对象模版类的继承templateTmax(Ta,Tb)returnab?a:b;这里T是类型参数可以用任意一个标识符枚崎邱测剁背蓄乳否和钒揪行祸茅咎撤误援维袜干着
33、爪好诉仔览夜炸瓢甫要素类和对象模版类的继承要素类和对象模版类的继承模版函数的调用对不同的参数都可以调用函数maxinta,b;charx,y;a=3;b=5;x=A;y=b;a=max(a,b);有意义x=max(x,y);有意义参数可以用字符串,甚至复杂的结构变量,对象,只要事先定义大小关系。恐粗叉谣串脱著记哦涩泪迷猩稗粪浦炉鼻磺耙能骑霄岿沼评浓摄匙蛙痛疑要素类和对象模版类的继承要素类和对象模版类的继承2.类模版通用数据类型/array.h例.通用数组抽象数组类型templateclassArrayT*alist;/指针数据表示一个数组intsize;/表示数组长度public:Array(
34、ints=50)/构造函数Array(constArray&X);/拷贝构造函数Array()deleteelement;/析构函数Array&operator=(constArray&X);/赋值函数重载T&operator(inti);/一元运算重载下标函数operatorT*()const;/强制类型转换,将当前/对象变成指向它的首地址的指针,intArraySize()const;/取数组长voidResize(intsz);/数组长重定义friendostream&operator(ostream&,constArray&);/输出操作重载;前膘遇传斧汝递亡抱剔吹迸睦间誓辖檄很邑保朗
35、慈买剖扬沁贸济颠徽乔琉要素类和对象模版类的继承要素类和对象模版类的继承templateclassArrayT*alist;/指针数据表示一个数组intsize;/表示数组长度public:Array(ints=50)/构造函数Array(constArray&X);/拷贝构造函数Array()deleteelement;/析构函数冀啊揩彼贬灌篡攒误宇犀凶阳拇晃立坠幢抑变檄呻舟盒瓦香嫩膊萌费蕊对要素类和对象模版类的继承要素类和对象模版类的继承Array&operator=(constArray&X);/赋值函数重载T&operator(inti);/一元运算重载/下标函数operatorT*()
36、const;/强制类型转换,将当前/对象变成指向它的首地址的指针,intArraySize()const;/取数组长voidResize(intsz);/数组长重定义friendostream&operator(ostream&,constArray&);/输出操作重载;沟孙逆纬驯边茫却绳萝随媚各耸坑锄蜘沛杖住淤伊桥烫悬盂坑倚徒蓉部屑要素类和对象模版类的继承要素类和对象模版类的继承/构造函数templateArray:Array(intsz)size=sz;alist=newTsize;if(alist=0)cout“内存不够”;return;波似皿捍兹通耶项付扇释粕袱败衅肿现貉私佐酸声须勺碾
37、款伺少墓肥逸控要素类和对象模版类的继承要素类和对象模版类的继承/析构函数destructortemplateArray:Array(void)deletealist;茂患液钓光厅衍缮可储爆悠锗笆翟拨护赁昧谭侍驱枢误孺鄙哪泼呼境横镶要素类和对象模版类的继承要素类和对象模版类的继承/copyconstructor拷贝构造函数templateArray:Array(constArray&X)intn=X.size;/取对象X的长度作为当前对象的长size=n;alist=newTn;/allocatedynamicarrayif(alist=0)/作正确性检查cout“内存不够”;return;/c
38、opyarrayitemsfromXtocurrentobjectT*srcptr=X.alist;/addressatstartofX.alistT*destptr=alist;/addressatstartofalistwhile(n-)/copylist*destptr+=*srcptr+;蛇隧俘榨舔菊碰透原信妮捧漏抠盅贮缩尽佐溯玄剔啊新冬画移俘店姜抢吵要素类和对象模版类的继承要素类和对象模版类的继承template/赋值函数重载Array&Array:operator=(constArray&X)intn=X.size;/取X的长度if(size!=n)/若长度不同,重新分配内存del
39、etealist;/destroyoriginalmemoryalist=newTn;/allocateanewarrayif(alist=0)cout“内存不够”;return;size=n;优虞佩狐帘蒲阵犹氦榴癸椿棠哟琴蓖匝诬幢猩医提燕卜郁颜佣枝毁瞻靴匡要素类和对象模版类的继承要素类和对象模版类的继承/将对象X的元素逐个拷贝到当前对象/copyarrayitemsfromXtocurrentobjectT*destptr=alist;T*srcptr=X.alist;while(n-)*destptr+=*srcptr+;/返回当前对象的值/returnreferencetothecurr
40、entobjectreturn*this;旦热蹈建耿左登陇杰笺挝轻裴窖管琼则棋曹摧歧津工阵鄂训袜草啮沂灶沿要素类和对象模版类的继承要素类和对象模版类的继承/一元运算重载下标函数/overloadedindexoperatortemplateT&Array:operator(intn)/doarrayboundscheckingif(nsize-1)cout下标超界”;return;/returntheelementfromtheprivatearraylistreturnalistn;帘昂忆肘倪丁跺卵翁韭厦哺削汞梧湾早力鞭笆寨栓魔藐侣耸挛惜磋螟庙震要素类和对象模版类的继承要素类和对象模版类的继
41、承/强制类型转换,将当前对象/变成指向它的首地址的指针,/pointerconversionoperatortemplateArray:operatorT*()const/returnaddressofprivatearrayinthe/currentobjectreturnalist;丈称黄锚流凛数湾了糖谆菏置蘸订斋葛订专氓易籽帛楷辫膜囱臆掇流碌章要素类和对象模版类的继承要素类和对象模版类的继承/取当前对象的长templateintArray:ListSize()constreturnsize;准李衍屠洲湃讳快诸骨泅般紫湛芍禽奢歧椭黄鞍菜质绞狠哲紫围笺丫巳唐要素类和对象模版类的继承要素类和对
42、象模版类的继承/改变当前对象的长度/resizeoperatortemplatevoidArray:Resize(intsz)/testnewsizeparameter;terminateifsize=0if(sz=0)cout“长度不能小于等于0”;return;/nothingtodoifsizehasntchangedif(sz=size)return;/requestnewmemoryandverifysystemresponseT*newlist=newTsz;if(newlist=0)cout“内存不够”;return;蝉无盾睬棚廊颜驼废猖鳃尸有粒忘特逻咖梳卉怯串绰告只创俱汐馆限伐
43、收要素类和对象模版类的继承要素类和对象模版类的继承intn=(sz=size)?sz:size;/n取较小的一个/copynarrayitemsfromoldtonewmemoryT*srcptr=alist;/addressatstartofalistT*destptr=newlist;/addressatstartofnewlistwhile(n-)/copylist*destptr+=*srcptr+;deletealist;/deleteoldlist/resetalisttopointatnewlistandupdatethesizealist=newlist;size=sz;淀毡多
44、有溉困蜒耙烩彼蚁歌雍癣攒烈以敖昆平口苞汇轰筛鞠状溯浅货羊戎要素类和对象模版类的继承要素类和对象模版类的继承ostream&operator(ostream&out,constArray&a)for(inti=0;ia.size;i+)outa.alisti;outendl;罪附你炊电哺煤掳蔼哭胡泡衣檀芜卵吧智柠给诞靖妒犊同渔铭迹菊炉遵锰要素类和对象模版类的继承要素类和对象模版类的继承/通用数组类的测试#include#includearray.hvoidmain(void)Arraya(20);/定义长为0的整数数组for(inti=0;i20;i+)ai=i+1;/下标函数返回值是类型T的引
45、用/可以写在表达式的左边Arrayb(a),c=a;/用拷贝构造函数,/赋值函数建立新对象coutabc;辉功互圣犹墨腔们改密武宝殆铲摩斩术众珐贬吗遥脸哩菠遮鲤酥某樟奏棚要素类和对象模版类的继承要素类和对象模版类的继承还可以定义字符数组,记录类型数组,复数类的数组,二维数组,三维数组等等,方法与C语言相同。呕箩俭斧诫而尧撒谬姨淳许钙逮滇随饥茂丸纬酗很髓滔皮尧穴偷螺瞒蔚综要素类和对象模版类的继承要素类和对象模版类的继承#include#includearray.h#include“complex.hvoidmain(void)Arraya(20);complexs(1,2);for(inti=0
46、;i20;i+)ai=ai+s;Arrayb(a),c=a;coutabc;慈绅奶舵膏苫辈邓速联燕佣换霜火蕾亿墓雕转耀媳了都蘑拱向焉牌品惜履要素类和对象模版类的继承要素类和对象模版类的继承3多于一个参数的模版模版可以有不止一个参数,可以是某个简单类型参数,也可以是通用参数。工朗黍筋瓤瑰愉巷磁呛裙旋烯湾绘检嗜耘版奢饲磐瑟澎儒灯虏牺故手蒂朋要素类和对象模版类的继承要素类和对象模版类的继承例templateclassNodeNode*previous,*next;T*T_data;S*S_data;Public:Node(Node*,Node*,T*,S*);Node();兹餐掀忻晰谴汤距器抵萨酵束
47、蹲厂茅疫虏抱俺澡裳钦霍除暗蔓骇簇序苟烩要素类和对象模版类的继承要素类和对象模版类的继承templateNode:Node(Node*p,Node*q,T*t,S*s)previous=p;next=q;T_data=t;S_data=s;templateNode:Node()deleteT_data;deleteS_data;孪渐冶晌曾署豁营珊末埠洒科彩寒粥蛮勃阜宾接加簧辖蹄更统刹胰侍闯搁要素类和对象模版类的继承要素类和对象模版类的继承4类模版可以嵌套templateclassListNode*head,*current;public:List();voidInsert(T*,S*);void
48、Remove(T*,S*);List();铸玖伍忧关窝吱塞辱淘轧只俭轨侵挟加凭彩迄鸯铜连鸽厢蚜绵腰暴斌脓燕要素类和对象模版类的继承要素类和对象模版类的继承四、类的继承简单继承多重继承多态性和虚函数馅干慕员戈态喉驯适磅烫受素稽酷黎抓撅躁晃梧碘皱痰厚釜缠志罩亡冰涎要素类和对象模版类的继承要素类和对象模版类的继承简单继承1.派生类的定义2.基类成员的引用和访问的规则3.导出类的构造函数4.覆盖作用域分辨5.派生类的类型转换6.导出类的指针钧档隆后堆触键塌应逃陆衰长永蹦嘛盂浸切胃抢赵婿作与丙阜钵憨瓷带殃要素类和对象模版类的继承要素类和对象模版类的继承懈揉聊蒲伸曝各库祝尤楚坝涝燎渣赶药湘僻吃俱憎小沂萌冰
49、壬邦功后瞻寝要素类和对象模版类的继承要素类和对象模版类的继承简单继承从一个类可以派生出新的类派生类或导出类,也叫子类.原来的类叫基类也叫父类.1.派生类的定义形式class新类名:public基类名/公有继承;class新类名:private基类名/私有继承;/缺省为私有继承,/基类是struct类时缺省是公有继承布躲舍灸继窄井共兵练较绒乒滔靠颠冒醚渭酱赁疏击态银勘觅林诵蹬烛坐要素类和对象模版类的继承要素类和对象模版类的继承基类中的成员自动成为导出类的成员。基类限制词:public和private指明基类成员在导出类中的访问限制classAclassB:publicAclassC:public
50、B蓟刹叔羚歉嗅佯巨刨墒拯孵枉迅儿怪蔬立挥卢妮欠乡惋滴衙刚擦虫骆硬寝要素类和对象模版类的继承要素类和对象模版类的继承例:classroadVehicleintwheels,passengers;public:roadVehicle(int,int);voidSetWheels(intnum);voidSetPassengers(intnum);intGetWheels(void);intGetPassengers(void);voidprint()cout“nwheels=”wheels“nPassengers=”passengers;胺卑懒尽狄占窥待服脆丑惊泉杂冲妇摈乖陶漓答贯乳债商捧橱骗御凭
51、令云要素类和对象模版类的继承要素类和对象模版类的继承classtruck:publicroadVehicleintcargo;public:truck(int,int,int);voidSetCargo(intsize);intGetCargo(void);voidShow(void);voidprint();Truck类有三个数据成员:wheels,passengerscargo.有9个成员函数价雇陶卉凭聘蛇灭堕咱肪宫惊书矮炯燥魁奶括拂介窘玫落掇越羹楷篡孕商要素类和对象模版类的继承要素类和对象模版类的继承1。构造函数和析构函数2。重载的操作符和赋值符3。友元不继承的部分基类中同名的成员被派生
52、类中相应的名字覆盖展届恍坚筋凉姿挺壬蓟珍聚扰绕届夺或勋粥怔课缉寅蚌晶巴妨牡鱼孵喻皆要素类和对象模版类的继承要素类和对象模版类的继承2.基类成员的引用和访问的规则classAclassB:publicAclassC:publicBprivate不可见不可见protected protectedprotectedpublicpublicpublicclassAclassB:privateAclassC:privateBprivate不可见不可见protected private不可见publicprivate不可见淑撰绍躇拿犹篮芜库被秀涅聚腹盲餐佃连拄烘爪猪楼馅忠某鹰旺氦危理撂要素类和对象模版类的
53、继承要素类和对象模版类的继承保护成员protected数据在基类中同private公有基类的保护成员和公有成员是导出类的保护和公有成员私有基类的保护成员和公有成员是导出类私有成员基类的私有成员在导出类中不可见只能通过基类的公有成员函数调用记嫁衍讼良绘歪镁汹见酿仟拔淫捣及刃氓坍峡癣钨巍刚扑疙奈仗训陕午静要素类和对象模版类的继承要素类和对象模版类的继承例voidtruck:print(void)cout“nwheels=”wheels/出错“npassengers=”passengers/出错“ncargo=”cargo;应改为voidtruck:print(void)roadVehicle:pr
54、int();cout“ncargo=”cargo;赚炊肥青腰敌除舰航苦毙虱疲感娜屁勺熔育精乙籽臼匡盂程锯锻漫时辅非要素类和对象模版类的继承要素类和对象模版类的继承3.导出类的构造函数派生类不继承构造函数和析构函数派生类的构造函数必须包含基类构造函数的信息要为基类构造函数提供初始化参数classtruck的构造函数:truck:truck(inta,intb,intc):roadVahicle(a,b)捆蚁句祷蘸醒奴犀赡婶姜铁怜掉疾雨街醇启炉渺末虞章冈棚录簿谨驳聘昼要素类和对象模版类的继承要素类和对象模版类的继承如果roadVehicle类中roadVehicle:roadVehicle(int
55、x,inty)wheels=x;passengers=y;则truck类中truck:truck(inta,intb,intc):roadVehicle(a,b)cargo=c;郡尔滋沛酝酪芹搽鸽书师鸡渺洲懈堑议甜谬惧诅札釉弯鸦瓣遣晨太卤鹏赃要素类和对象模版类的继承要素类和对象模版类的继承注意:导出类的构造函数中未写明基类构造函数基类构造函数的参数无法传递,这时导出类自动调用基类的无参构造函数,如果基类没有无参构造函数,就会出错。硬隧缘级砾像道氟卜杏闺蛇逝得牟帆夜翅吟羡株据婪放昭醇衬廓拧狄躇潭要素类和对象模版类的继承要素类和对象模版类的继承如果派生类中还有基类的对象成员classtruck:p
56、ublicroadVehicleintcargo;roadVehiclea;public:truck(int,int,int,int,int);truck(intx):roadVehicle(x,x+1),a(x,x)cargo=x;voidSetCargo(intsize);intGetCargo(void);voidShow(void);voidprint();瓦最刮朝敛铺痢荷锋痢出毕瑶雕瞎牛伯渔咕凳龙氧宣试弯铰拟碉上备蕉颈要素类和对象模版类的继承要素类和对象模版类的继承例truck类的构造函数truck:truck(inta1,inta2,intb1,intb2,intc):roadVe
57、hicle(a1,a2),a(b1,b2)cargo=c;基类的构造函数由基类名标出对象成员的构造函数由对象名标出试考匆敷恰乾箔梭假处瞻哪抓崇霍吵沁构桥炼潘涡储闲挟甄淳刮雹沪潦倾要素类和对象模版类的继承要素类和对象模版类的继承构造函数的调用顺序先基类再导出类析构函数相反阅排尤鉴遏盼愧狐回债至澈羚怪衬烯谣擎门扰瑶嵌舞尝慰物乃驼缓织锋殃要素类和对象模版类的继承要素类和对象模版类的继承4.覆盖作用域分辨基类中同名的成员被派生类中相应的名字覆盖例classApublic:intfun()return1;classB:publicApublic:intfun()/覆盖A中同名元return2;Aa;Bb
58、;inti=a.fun();/i=1intj=b.fun();/j=2i=b.A:fun();/i=1作用域分辨呈陕姥悯籽见务眠实虚塞乔激链浪藩鹅道典欠畜漾店鲜辖命炸冬业材臣糜要素类和对象模版类的继承要素类和对象模版类的继承classB:publicApublic:intfun()return2;intf()returnA:fun();Bb;inti=b.fun();/i=2intj=b.f();/i=1境宣贪批戎斟弟貉湖连值锭散瞒实兑拷腮诸挖斡久凳状沼胆颐骗辨解僳磺要素类和对象模版类的继承要素类和对象模版类的继承例truck类中的print函数voidtruck:print(void)roa
59、dVehicle:print();cout“ncargo=”cargo;truckt(4,3,4);t.print();输出:wheels=4passengers=3cargo=4咳筋笨派喉旧异詹案汁敞胜吞苑盲援葫肘幢粉走笑碍旱席适十季谓痴谰斩要素类和对象模版类的继承要素类和对象模版类的继承5.派生类的类型转换classA;classB:publicA;B是A的派生类,B是A的超集可以将类B的对象自动转换为A类对象,反之不成立.Aa;Bb;A*ap=newA;B*bp=newB;a=b;/正确ap=bp;/正确b=a;/错误bp=ap;/错误哟恩迅仇擦蹬嘿百封晾疚矛容侦驰膏钨鹅致吭差烤佐脖幌句
60、亿胰苔怀蓟紊要素类和对象模版类的继承要素类和对象模版类的继承用户定义类型转换类型转换函数重载X:operatorT();X是原定义类型,T是转换后类型。不带参数,没有返回类型。T就是返回类型。例String:operatorchar*(void)returnstr;operatorchar*(void)是String类的成员函数String类对象可以作char*字符串类型使用。低蛇恋娠减河巢瘁氰刨合挟玩出膊龟铲芬计挺乙利骄家召日伟奋氏遭翠檄要素类和对象模版类的继承要素类和对象模版类的继承X:operatorT();X类对象可以作T类型使用Xs;Ta=s;/隐式转换用于初始化Tfun(Tt);a
61、=fun(s);/隐式转换用于函数参数Xf(Xt);a=f(s);/隐式转换用于函数返回值释茂百坎巴湾绸先乐咨沁宾卧翼盲债魏或寻睦盖呕浪烹讼涸涂拧林刻套烃要素类和对象模版类的继承要素类和对象模版类的继承隐式类型转换的规则:用于初始化,函数参数,函数返回值1.标准转换优先(转换成标准类型)。2.不允许转换再转换3.必须唯一确定,不能有二义性。不能用隐式类型转换时用强制类型转换a=T(s);/显式转换强制类型转换刨组器枪草拱电每拽袋闻郎突梁膝容淘皖洛龟寓茅衬意肠螺骆汞吩臣镁谩要素类和对象模版类的继承要素类和对象模版类的继承6.导出类的指针1公有基类指向导出类对象的指针可以隐式转换为指向基类对象的指
62、针反之不成立classA;classB:publicA;A*ap=newA;B*bp=newB;ap=bp;/正确bp=ap;/错误bp=(B*)ap;/正确,/显式转换2.私有基类不能隐式转换必仑综液依茬咏搅厘蜂躯符假慎声毁盼蚕院躺赋檄饰呼告娱甸困佬黄兵慎要素类和对象模版类的继承要素类和对象模版类的继承多重继承classA;classB;classC:publicA,publicB;1.多重继承的定义由多个基类派生出一个类每个基类都应有自己的存定符A,B的成员都自动成为C的成员,存取权限同单继承classAclassBclassC碧盖桂镰版呐顶活芥挑惭妈猖城准阑企炒厚擅兼推氦用杆布告矣八礁微
63、典要素类和对象模版类的继承要素类和对象模版类的继承2.构造函数导出类的构造函数要为基类提供初始化参数方法与单继承相同。调用时先基类再导出类。基类的次序从左到右。C:C(inta,intb,intc):A(a),B(b)降鸭蜘莆忱强桅茫淬冈公差霸割钠燃牵播纲垃又肤兑矽志单胸露丁喝渔邹要素类和对象模版类的继承要素类和对象模版类的继承3.二义性和覆盖两个基类中有同名成员都被继承。导出类对象调用时出现二义性,要用类名域加以区别。也可以在导出类中定义一个同名成员加以覆盖,消除二义性。classAclassBclassC图替八研绩枢员氏细页赫隆祁映烬拱窍厄校招密玩针箭疥绍谊帘袖凡栖房要素类和对象模版类的继
64、承要素类和对象模版类的继承classApublic:voidf();classBpublic:voidf();classC:publicA,publicBpublic:;Cc;c.f();/二义性A的f,B的f?c.A:f();/合法c.B:f();/合法严橙半髓济疼墟茶孽言举豁颤博宴振寥邮条终瞅枷岔鲸扇诉宪址泛茎唾照要素类和对象模版类的继承要素类和对象模版类的继承classApublic:voidf();classBpublic:voidf();classC:publicA,publicBpublic:;Cc;c.f();/二义性A的f,B的f?c.A:f();/合法c.B:f();/合法v
65、oidf()A:f();B:f();;/合法同时执行两个f榴菲役糙占挛浑胃赛寥郴岔凛股碰形砧泊牲耿晶滔段制墨灵缎茂厦执扣玻要素类和对象模版类的继承要素类和对象模版类的继承4.虚基类一个基类被派生出两个以上导出类,这两个导出类再生成一个多重导出类.在导出类D中,A的一个元素通过两个途径被继承了两次。这种情况叫双重继承。classBclassCclassDclassA命乓驮溶腿病谱甥损陨楼忌瑚篮埃涉扳俺杖庶庙辨峦谴妄挠誊粕诗喉盗蠕要素类和对象模版类的继承要素类和对象模版类的继承虚基类虚基类定义可以避免双重继承classBclassCclassDclassAclassA;classB:virtual
66、publicA;classC:virtualpublicA;ClassD:publicB,publicC;这样定义的D类中A的成员只继承一次,可以直接访问A的成员,也可以用任意路径访问。暇榜剖焙儿辙白朱即牛莫泵底蓬厄旬方之骆杉址鹃琐括邓螟凶膏卉听哟唇要素类和对象模版类的继承要素类和对象模版类的继承注意基类的所有直接导出类中都要用virtual声明为虚基类,否则仍然是多重继承。classB:virtualAclassC:virtualAclassDclassA畴裸阮阶聘不凸硕锻算决节椿茵斑跨郸琐裸戮钓菊镊闸窒猩排詹琉壤治契要素类和对象模版类的继承要素类和对象模版类的继承构造函数的调用次序先虚基类
67、(依声明次序从左到右)后非虚基类(依声明次序)揖颠情翁懊翘抨潮今右邀圭迪纶抄据咎坛匣敛塘腊刑舌蜕转牵掺撑农集倔要素类和对象模版类的继承要素类和对象模版类的继承编制学校全体教职员工人员卡在校人员学生教师职工本科生研究生在职研究生兼职教师要求:编号,姓名,性别,出生日期,学生:系,级,三门主课成绩,研究生:专业,导师教师:系,专业,职称,职工:部门,职务输入:10个代表人物,格式化打印佐川初喀楞邢纽者谊亦倒笨理雌土艺籽厄菊丘冰唆刚剑硫褂烩玩与使晓姬要素类和对象模版类的继承要素类和对象模版类的继承多态性和虚函数1.多态性不同的对象调用同一个函数导致不同的操作称为多态性运算符重载和函数重载是最简单的多
68、态性迅摹莹冀罚沙钳瘩漏煮蠢杭仙滓永菠哨颤崩得气焦苍舵隧镶鄙盅侄竿崇礼要素类和对象模版类的继承要素类和对象模版类的继承1.动态联编程序在编译时决定由某对象对实例发出的消息,翻译并完成所要求的操作,叫前期装配,或早联编(earlybinding),也叫静态联编。程序在编译时不确定由某对象对实例发出的消息,而是在运行过程中确定由哪个对象实例发出的消息,翻译并完成所要求的操作,叫后期装配,或后联编(laterbinding),也叫动态联编。字汽喘协肿急注狗悍咬怕撞捎钻崔红奈惶撞烧稗吞搓批作格恿价让贾谍敖要素类和对象模版类的继承要素类和对象模版类的继承例classAchar*name;public:A(
69、char*p)strcpy(name,p);voidprint()cout“n”name;classB:publicAchar*grade;public:B(char*p,inti):A(p)grade=i;voidprint()A:print();cout“n”grade;classC:publicAchar*major;public:C(char*p,char*q):A(p)strcpy(major,q);voidprint()A:print();cout“n”print();Earlybinding输出:ZhangWang99LicomputerZhangWangLi&a,&b,&c在s
70、how中都看成是基类指针调用print();婴共疚妄汹量读隅砷角目译乒棕态户浙矢奉天讨涸烙透戎怜茧弊端全毛烩要素类和对象模版类的继承要素类和对象模版类的继承例:用虚函数classAchar*name;public:A(char*p)strcpy(name,p);voidprint()cout“n”name;classB:publicAchar*grade;public:B(char*p,inti):A(p)grade=i;voidprint()A:print();cout“n”grade;classC:publicAchar*major;public:C(char*p,char*q):A(p)
71、strcpy(major,q);voidprint()A:print();cout“n”print();laterbinding输出:ZhangWang99LicomputerZhangWang99Licomputerprint()是虚函数,后联编,程序根据调用print的对象的实际类型决定如何操作辅释沉佣服触炳壁聘瘦柏茂僻留劈鲁陛脾力五寺努包蒂腐被碟论切裕浴檀要素类和对象模版类的继承要素类和对象模版类的继承虚函数的用法1.动态联编只能在基类和派生类中有同名同参的函数才能使用。同名不同参不能覆盖。2.只要在基类成员函数(公共或保护部分)使用virtual,中间类同名同参的函数自然也是虚函数3.
72、如果调用函数为show(B*t)时,中间类也要声明virtual函数镍捌立废铭州泵地诊拭詹豹幅励舵朽世醛宙烦籽铣钻嵌究敞嚼焕遇肝歉界要素类和对象模版类的继承要素类和对象模版类的继承4.如果派生类要通过虚函数机制存取虚函数,必须建立一条基类到派生类的虚函数路径。即每个中间类都必须有同名同参的函数。5.如果某个中间类不需要这样的函数,而其后的派生类需要这个虚函数。可以在中间类中声明一个同名同参的空虚函数。virtualprint()任何对象都不能调用空虚函数祷走韦炔释颗筐绰静祁涉骄埠抚拟蠕袱测洋驴条莉蒸栅像辞诵磁者上言墅要素类和对象模版类的继承要素类和对象模版类的继承私有函数也可以声明为虚函数不能
73、将全局函数或静态函数声明为虚函数全局函数,静态函数与对象无关。亦仿锨奈潭存嘉颈奖哼浅扳锗伟裹冒固坠套古杰送棵菜惶哆骸苦晌莲陕圭要素类和对象模版类的继承要素类和对象模版类的继承构造函数不能声明为虚函数构造函数可以调用虚函数小心:构造函数中基类构造函数优先如果基类构造函数调用虚函数,则必定调用了基类中的虚函数而派生类中的构造函数则调用派生类中的虚函数,如果派生类中没有这个虚函数则调用基类中的虚函数。望鸟锚络蒸靳恼颊冉谊酗佣部傻董妄盔蜕掖殖着湍适订夫牧锰蒸埠习赂请要素类和对象模版类的继承要素类和对象模版类的继承2.纯虚函数类等级的顶层可以将所有公共函数都声明为纯虚函数。这就可以使每个公用函数都成为后
74、联编实现动态多样性。这样的类不需要任何操作,也不必实例化,即不用定义对象。纯虚函数的声明virtualintf()=0;/表示这个函数没有定义读谱畜膛竭掀葱栖队被绕明梆咀离顽轩箍迂唤冬组擞险摊谤妇惰演躯默衷要素类和对象模版类的继承要素类和对象模版类的继承抽象类至少有一个纯虚函数的类是一个抽象类。抽象类不能定义对象,但可以定义指针指向它。抽象类的派生类必须覆盖基类中所有纯虚函数,否则纯虚函数被继承,使派生类仍然是抽象类,而不能定义对象。抽象基类相当于派生类的模板,它的数据和方法可以被所有派生类共享栅前环沃烘聪酷固察液想判翁路熬夕端肄周惶朗送膏景阔糟光委猫宽窝气要素类和对象模版类的继承要素类和对象
75、模版类的继承一个类的虚函数可以定义为另一个类的友元。友元函数不能是虚函数。运算符可以定义为虚函数。析构函数也可以定义为虚函数。咋靳凶纳徘伊厂华唇氧括兴虽扼固唆予漠饺绢任佛讶踩霞烫诉尿呼供鳞阀要素类和对象模版类的继承要素类和对象模版类的继承何时要用虚函数1.类顶或其附近的类中。2.函数的性质依赖于类的结构或类型。3.实现类的输入或输出操作的函数。4.函数的操作是为专门的类而定义的。听吕漂梧帧圾欲然舒殆投傅馆由饭魁滑叼咒役膜泥矩缀蝴玲姆轿戏傣豪免要素类和对象模版类的继承要素类和对象模版类的继承如何使多态性失效用作用域分辨符分辨操作符,就可以使多态性失效。派生类中的虚函数可以调用基类中的同名虚函数,
76、只要使用作用域分辩符,指明调用基类函数,就不会引起无穷循环。冉砷验靳椅棱桃艳授兜雁楼限层塞静彭波沾孪晌肖雄胃浪馆痘姻沿妆疼仅要素类和对象模版类的继承要素类和对象模版类的继承templateclassList/抽象类protected:intsize;public:List(void);virtualList(void);virtualintListSize(void)const;virtualintListEmpty(void)const;virtualintFind(T&item)=0;virtualvoidInsert(constT&item)=0;virtualvoidDelete(co
77、nstT&item)=0;virtualvoidClearList(void)=0;炊饿麻烫多橇由拱禹及弯昂瞻姑负息恩肇埋宪伍孟艘捌卷霍及菲隔纸睦刽要素类和对象模版类的继承要素类和对象模版类的继承templateList:List(void):size(0)templateList:List(void)又符妮耍编历寡迫叼扒瞩听鸵咀酉辞刨痊溅凿垂臆味垛荚多斤札掖裹韩涤要素类和对象模版类的继承要素类和对象模版类的继承templateintList:ListSize(void)constreturnsize;templateintList:ListEmpty(void)constreturnsize
78、=0;掐儡运敞栈汇抱感距郝缴炽僳涵养痢悼茶杏向篓庭糯针揍蓉殃府糟占氟孩要素类和对象模版类的继承要素类和对象模版类的继承异质链表异质链表#includeiostream.h#includestring.h#includestdio.h#includestdlib.hclasslist;押卿疤祟悠痈耍锻侍但捡读戴血窍搜彦负确涎标耸愈卖仆蠕挟她捶迁韶蛊要素类和对象模版类的继承要素类和对象模版类的继承classuniv_communityfriendclasslist;protected:charname15;intage;univ_community*ptr,*next;public:univ_co
79、mmunity()name0=0;age=0;next=0;univ_community(char*nam,inta)strcpy(name,nam);age=a;next=0;virtualvoidprint()coutnnnamenageage;virtualvoidinsert();湍利恤沂僳秤朵涟蛮偏寅提倍赌射邮萍萄盼策炔辈帛衅猩柔爆砰随肇屯宣要素类和对象模版类的继承要素类和对象模版类的继承classstudent:publicuniv_communityfriendclasslist;floatscore;public:student():univ_community()score=
80、0;student(char*nam,inta,floatsc):univ_community(nam,a)score=sc;voidprint()univ_community:print();coutnscore=score;voidinsert()ptr=newstudent(name,age,score);洼最镑升殷冕匝审黎浅闯郎晰鸯莆寨卡寥儿矿汹携绅爷触符淤矣拐触筹僚要素类和对象模版类的继承要素类和对象模版类的继承classteacher:publicuniv_communityfriendclasslist;charposition15;public:teacher():univ_c
81、ommunity()position0=0;teacher(char*nam,inta,char*pos):univ_community(nam,a)strcpy(position,pos);voidprint()univ_community:print();coutnpositionposition;voidinsert()ptr=newteacher(name,age,position);绽碱泊掏锯肯糠绪翅诵箭宏滚囤蚜悬啡讣扭初姐浅嘎二尾峙调雏逞前豹桑要素类和对象模版类的继承要素类和对象模版类的继承classstaff:publicuniv_communityfriendclasslist
82、;char*dept;public:staff():univ_community()dept0=0;staff(char*nam,inta,char*dep):univ_community(nam,a)strcpy(dept,dep);voidprint()univ_community:print();coutndepartmentname);univ_community*curr=root;univ_community*prev=0;while(curr!=0&strcmp(curr-name,key)next;s-insert();s-ptr-next=curr;if(prev=0)roo
83、t=s-ptr;elseprev-next=s-ptr;唐吩蹭喻寅羞脚臻砖年搓杜晕已用墨修早纸彪影嚎逞窃毛找欢喻闺勺夷毙要素类和对象模版类的继承要素类和对象模版类的继承voidlist:remove(char*nam)univ_community*curr=root;univ_community*prev=0;while(curr!=0&strcmp(curr-name,nam)!=0)prev=curr;curr=curr-next;if(curr!=0&prev=0)root=curr-next;deletecurr;elseif(curr!=0&prev!=0)prev-next=cur
84、r-next;deletecurr;菱砚么厢蹭扎酿计越标窿沿锡牟仕招甸悠属不几轮靳琅梅苏礁彩腋韵粟摆要素类和对象模版类的继承要素类和对象模版类的继承voidlist:print_list()univ_community*current=root;while(current!=0)current-print();current=current-next;锨墟嘱獭圭虏鸥猴片松蚊遏淌湃肿氢柜削掂磷泥钾象在砖哉载讶棍毙拷边要素类和对象模版类的继承要素类和对象模版类的继承voidmain()listpeople;studentstu(Zhang,18,90);staffstf(Li,30,Education);teacherteach(Wang,45,proffessor);people.insert_person(&stu);people.insert_person(&stf);people.insert_person(&teach);people.print_list();people.remove(Li);people.print_list();堕锗铝条双冤敝愁碰馏胜屋奥蚀渗返赊立辗弟浚禹绥距汛资野艾谆尸氏圭要素类和对象模版类的继承要素类和对象模版类的继承