c++程序设计基础ppt课件_第1页
c++程序设计基础ppt课件_第2页
c++程序设计基础ppt课件_第3页
c++程序设计基础ppt课件_第4页
c++程序设计基础ppt课件_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.,1,第十一章程序设计基础,.,2,问题的提出,结构化程序设计方法将解决问题的重点放在如何实现过程的细节方面,而把数据和对数据进行操作的函数截然分开,以数据结构为核心,围绕着功能实现或操作流程来设计程序。程序的基本形式是主模块与若干子模块的组合,即一个主函数(main函数)和若干子函数。程序以函数为单位,函数之间以数据作为连接的纽带。把数据和操作分开对待,一旦数据的格式或结构发生变化,相应的操作函数就得改写,而且对于核心数据的访问往往也得不到有效控制。,.,3,教学目标,理解面向对象的概念,理解面向对象程序设计的思想,理解面向对象程序设计的基本方法。理解抽象、封装、继承、多态等概念。理解类与对象的概念,掌握程序设计中类与对象的定义方法。理解基类、派生类概念、了解派生类的定义方法。理解多态性与虚拟函数的概念,了解虚拟函数的定义方法。,.,4,1.函数的重载,函数的重载:一个函数可以对应多个函数的实现,可以实现不同的功能重载函数:具有相同的名称,具有不同的参数个数或参数类型,.,5,【例】用重载函数求两个整数或实数中的最大数,#includeintmax(inta,intb)if(ab)returna;elsereturnb;floatmax(floata,floatb)if(ab)returna;elsereturnb;,voidmain()inta,b;floatx,y;cinab;cinxy;coutmax(a,b)=max(a,b)endl;coutmax(x,y)=max(x,y)xy;coutmax(x,y)=max(x,y)x)x=y;if(zx)x=z;returnx;main()inta,b,c;coutabc;if(c-32768)coutmax(a,b,c)=max(a,b,c)endl;elsecoutmax(a,b)=max(a,b)endl;,赋予默认的参数必须放在形参表的最右端,注意:不要同时使用带默认参数的函数和重载函数(参数个数不同),.,9,3.C+新增运算符,作用域运算符,:指定变量的作用域,可以访问当前作用于之外的变量,#includeintx=20;/全局变量voidmain()floatx=8.9;/局部变量coutx=xendl;/输出局部变量,cout“x=”:xendl;/输出全局变量,.,10,动态内存分配与撤销运算符,new自动为变量分配正确长度的内存空间分配成功则返回指定类型的一个指针若不成功则返回0格式:new类型初值,int*p;p=newint(10);/为指针分配10个字节的内存单元,int*p;p=newint10;/为指针分配10个整型元素内存单元,.,11,Delete必须用于先前用new分配的有效指针格式:delete指针变量;,.,12,#includevoidmain()int*p;p=newint10;/为指针p分配10个元素的整型数组/的内存单元if(!p)/判断返回的是否为空指针cout内存分配失败endl;for(inti=0;i10;i+)pi=i;/为p所指内存单元赋值coutpi;/输出p所指内存单元的值deletep;/释放为指针p分配的内存单元,.,13,4.类和对象,类的定义,将不同类型的数据和对这些数据相关的操作封装在一起,class类名private:私有成员数据及函数;protected:保护成员数据及函数;public:公有成员数据及函数;,只能被本身的成员函数调用,外界不能调用,只能被本身的成员函数调用,可以被继承,类与外部的接口,任何外部函数都可以访问公有数据或函数,classEmployeeprivate:/私有成员数据charEmployeeID20;charEmployeeName50;charsex;public:/公有成员数据及函数;Employee();voiddisplay();,类定义只说明产生了一种新的数据类型,并没有为该类数据分配内存空间。,.,14,对象的定义,两种方式定义对象:,1先定义类再定义变量,classEmployeeprivate:/私有成员数据charEmployeeID20;charEmployeeName50;charsex;public:Employee();/公有成员数据及函数;voiddisplay();Employeeep1,ep2;,2定义类的同时定义变量,classEmployeeprivate:/私有成员数据charEmployeeID20;charEmployeeName50;charsex;public:Employee();/公有成员数据及函数;voiddisplay();ep1,ep2;,.,15,成员函数的定义,只有类的成员函数才能存取该类对象的私有数据成员,classrect_areaprivate:/私有成员数据floatlen;floatwidth;floatarea;public:/公有成员数据及函数;voidarea()area=len*width;cout“area=”areaendl;rect_arearectangle;,方法的实现(成员函数的函数体)可以在类的内部完成(类的内联函数),也可以在类的外部实现,而且可以与类的定义放在同一个源文件中,也可放在不同的源文件中。,.,16,classrect_areaprivate:/私有成员数据floatlen;floatwidth;floatarea;public:/公有成员数据及函数;voidarea(floatlen,floatwidth);;rect_arearectangle;,若成员函数的实现在类定义的外部,则定义是必须在函数名前加上类名,中间用“:”隔开,voidrect_area:area(floatlen,floatwidth)area=len*width;cout“area=”areaendl;,一般将类的定义放在.h的文件中,而把成员函数的实现放在一个与.h文件同名的.cpp文件中,.,17,类的成员数据可以是任意类型,但不能对成员数据初始化,classrect_areaprivate:/私有成员数据floatlen=10;floatwidth=20;floatarea;public:/公有成员数据及函数;voidarea()area=len*width;cout“area=”areaendl;rect_arearectangle;,.,18,类的私有成员,只有类本身的成员函数或其友元函数可以使用。,#includeclassrect_areaprivate:floatlen;floatwidth;floatarea;public:voidqarea()area=len*width;coutarea=areaendl;rectangle;,voidmain()rectangle.len=10;rectangle.width=20;rectangle.qarea();,public:,.,19,类的公有成员,可以被类本身的成员函数和外部函数可以使用。,#includeclassrect_areaprivate:floatarea;public:voidqarea(floatlen,floatwidth)area=len*width;coutarea=areaendl;rectangle;,voidmain()rectangle.qarea(10,20);,.,20,内联函数,在类内部定义的成员函数。可提高程序的运行速度,在调用处用内联函数体的代码替换,不需要进行现场处理,节省了时间和空间开销。,#includeclassrect_areaprivate:floatarea;public:voidqarea(floatlen,floatwidth)area=len*width;coutarea=areaendl;rectangle;,#includeclassrect_areaprivate:floatarea;public:voidqarea(floatlen,floatwidth);rectangle;,voidrect_area:qarea(floatlen,floatwidth)area=len*width;coutarea=areaendl;,inline,内联函数一定在调用前定义,且不允许有循环语句和开关语句,无法递归调用。,voidmain()rectangle.qarea(10,20);,.,21,构造函数,类体中不允许对数据成员进行初始化用构造函数来初始化对象的数据成员,使对象在被使用之前处于一个合理的状态。,为什么要用构造函数?,classclassnamepublic:classname();/构造函数;,一般声明为public构造函数的名字必须与所在的类名相同没有返回值,也不需要加void类型声明在定义类的对象时,由系统自动调用该类的构造函数,而且只能调用一次。,若在类定义时没有定义任何构造函数,由系统自动生成一个不带参数的默认构造函数classname:classname()在程序中定义一个对象没有指明初始化,则编译器按默认的构造函数来初始化对象,对象的所有数据初始化为0或空。,.,22,#includeclassrect_areaprivate:/声明下面部分为私有数据成员floatarea;floatlen;floatwidth;public:rect_area()/构造函数len=10;width=20;area=len*width;coutarea=areaendl;,voidmain()rect_areaqarea;,.,23,#includeclassrect_areaprivate:/声明下面部分为私有数据成员floatarea;floatlen;floatwidth;public:rect_area(floatlen=10,floatwidth=20)/构造函数可以有默认参数area=len*width;coutarea=areaendl;,voidmain()rect_areaqarea;,构造函数在定义对象的同时调用,如果要通过实参给构造函数传递数据,可以采用如下形式来定义对象。类名对象名(实参表);,voidmain()rect_areaqarea;rect_areaqarea1(30,20);rect_areaqarea2(20,20);,构造函数可以有默认参数,默认参数可以改变,.,24,#includeclassrect_areaprivate:/声明下面部分为私有数据成员floatarea;floatlen;floatwidth;public:rect_area()/构造函数area=10*20;coutarea=areaendl;,rect_area:rect_area(floatlen=10,floatwidth=20)area=len+width;coutarea=areaendl;,voidmain()rect_areaqarea1(30,20);rect_areaqarea2;,无法确定调用哪个构造函数,有默认参数的函数和没有参数的函数重载时,可能产生二义性,.,25,析构函数,用于回收构造函数动态申请的存储空间构造函数的名字必须与所在的类名相同,前面加没有返回值,也不需要加void类型声明不允许带参数,且不能重载,一个类只有一个析构函数,classclassnamepublic:classname();/析构函数;,若在类定义时没有定义任何析构函数,由系统自动生成一个不带参数的默认构造函数classname:classname()函数中定义对象后,这个对象的生存期从开始定义到函数结束,此时自动运行解析函数;用new运算符创建的对象用delete运算符释放时,系统自动运行解析函数。,.,26,#include#includeclassstudchar*name;intave;public:stud(char*str,intk)/定义构造函数intlen;len=strlen(str)+1;name=newcharlen;strcpy(name,str);ave=k;,stud()/析构函数deletename;coutnameisdelected!endl;voiddisplay()/成员函数coutnamesaveisaveendl;,voidmain()studstudent(LiuLin,86);student.display();,.,27,#include#includeclassstud/类定义char*name;intave;public:stud(char*str,intk);stud();voiddisplay();,stud:stud(char*str,intk)/在类定义之外定义构造函数intlen;len=strlen(str)+1;name=newcharlen;strcpy(name,str);ave=k;,stud:stud()/在类定义之外定义析构函数deletename;coutnameisdelected!endl;,voidstud:display()coutnamesaveisaveendl;,voidmain()studstudent(LiuLin,86);student.display();,.,28,类的友元,友元函数或友元类的成员函数可以访问类的私有成员,友元函数,在类中声明,在类外定义声明时在函数类型前加上friend可将其他类的成员函数或非成员函数声明为该类的“友元”,.,29,#includeclassfrect_areaprivate:/声明下面部分为私有数据成员floatarea;floatlen;floatwidth;public:frect_area(floatx,floaty)len=x;width=y;friendvoidrect_area(frect_areaclass_sub);/声明函数rect_area为类frect_area的友元;,voidrect_area(frect_areaclass_sub)/友元函数的定义class_sub.area=class_sub.len*class_sub.width;/通过友元函数访问类的私有成员coutarea=class_sub.areaendl;voidmain()frect_areaprect(5,2);rect_area(prect);,定义与普通函数定义基本相同,而与成员函数的定义不同,前面不需要加类名和作用域运算符:,.,30,友元类,若A是B的友元类,则A的所有成员函数都是B的友元函数,都可以访问B的私有成员和保护成员。,classBfriendclassA;/声明A是B的友元类;,友元类不一定是相互的,.,31,#includeclassAprivate:/声明下面部分为私有数据成员floatarea;floatlen;floatwidth;public:A(floatx,floaty)len=x;width=y;friendclassB;/将B类定义为A类的友元类;,classB/B类的成员函数可以直接引用A类的私有数据成员public:voidrect_area(Aa)a.area=a.len*a.width;coutarea=a.areai=j;/this指针的应用Aadd(intk)this-i*=k;return*this;voiddisp()/用于输出的成员函数coutiendl;coutthevalueofthispointeristhisb)returna;elsereturnb;,voidmain()max_classoutmax;intx,y;floata,b;coutxy;/输入x,ycoutab;/输入a,bcoutmax(x,y)=outmax.max(x,y)endl;/输出结果coutmax(a,b)=outmax.max(a,b)a)a=c;coutmax(a,b,c)=ab)coutmax(a,b)=aendl;elsecoutmax(a,b)=bendl;,voidmain()max_classA(9,5,8);/声明对象max_classB(5.6,9.3);,系统根据不同的参数分别调用不同的构造函数,.,36,1.重载为类的成员函数,在类内定义运算符重载函数的格式为:operator(),以operator为关键字,编译器可以很容易将运算符重载函数与其他成员函数区别开来。,运算符重载的两种方式,在类外定义运算符重载函数的格式为::operator(),.,37,classComplexfloatReal,Image;public:.Complex(floata=0,floatb=0)Real=a;Image=b;Complexoperator+(constComplex,【例】实现复数类的“+”,“-”等重载运算(运算符重载.cpp),ComplexComplex:operator+(constComplex,.,38,voidmain()Complexc1(2,3),c2(4,-2),c3;c3=c1+c2;c3=c1+5;c3=-c1;,编译器将c1+c2解释为:c1.operator+(c2),将c1+5解释为:c1.operator+(5),第1个运算量是对象,第2个运算量是参数。,将-c1解释为:c1.operator(),当用成员函数实现运算符的重载时,重载函数的参数个数只能是0个或1个。分别实现:一元、二元运算符的重载。,.,39,2.重载为友元函数,.,40,classComplexfloatReal,Image;public:.friendComplexoperator+(constComplex,在main()函数中,若有Complexc1,c2;则编译器将c1+c2解释为:operator+(c1,c2),将c1解释为:operator(c1),【例】用友元函数实现复数类的“+”和“”重载运算,.,41,当用友元函数实现运算符的重载时,重载函数的参数个数只能是1个或2个。分别实现:一元运算符重载、二元运算符重载,3.两种重载方式的比较,.,42,因此:对一般的二元运算符重载为友元函数比重载为成员函数更优越。但是对于赋值运算符,将其重载为成员函数较好,因为赋值运算符是一个二元运算符,其语法格式为=,第一个运算量必须是对象(变量也是对象),通过对象调用成员函数比较自然。若重载为友元,则可能会出现5.6=c这样的表达式,与赋值表达式的语义不一致。,.,43,运算符重载,将C+语言中已有的运算符赋予新的功能,与运算符的本来含义不发生冲突,使用时根据运算符所在位置判断具体执行哪种运算。,两种:重载为类的成员函数或类的友元函数。,重载为类的成员函数,首先在定义时使用如下格式用声明,类型operator运算符(形参表);,按如下格式定义重载运算符函数,返回值类型类名:operator(形参表);,.,44,#include#includeclassaddclass/声明一个类intnum;public:addclass(inta=0)/构造函数num=a;addclassoperator+(addclassa);/声明重载的运算符+voiddisp();,addclassaddclass:operator+(addclassA)/定义重载的运算符函数实现addclassB;B.num=num+A.num;returnB;,voidaddclass:disp()coutz=numendl;,voidmain()addclassx(3),y(4),z;/声明addclass的3个对象z=x+y;/对象x调用重载运算符+与对象y相加,并将返回值赋给zz.disp();,重载运算符作为类的成员函数时,处理的数据有一个来自对象本身,运算符重载的参数比正常运算符少1,.,45,重载为类的友元函数,更灵活,可以自由的访问任何数据成员,所需要的操作数都需要由形参来传递,.,46,#include#includeclassaddclass/声明一个类intnum;public:addclass(inta=0)/构造函数num=a;friendaddclassoperator+(addclassa,addclassb);/运算符+重载友元函数voiddisp();,addclassoperator+(addclassA,addclassB)/定义运算符重载友元函数实现return(B.num+A.num);voidaddclass:disp()coutz=numendl;,voidmain()addclassx(3),y(4),z;z=x+y;/使用重载运算符z.disp();,.,47,classStudentintnum;charname30;charsex;public:voiddisplay()/对成员函数display的定义coutnum:numendl;coutname:nameendl;coutsex:sexendl;,6.继承,.,48,classStudend1intnum;/此行原来己有charname20;/此行原来己有charsex;/此行原来己有intage;charaddr20;public:voiddisplay();/此行原来己有coutnum:numendl;/此行原来己有coutname:nameendl;/此行原来己有coutsex:sexendl;/此行原来己有coutage:ageendl;coutaddress:addrendl;,.,49,利用原来定义的类Student作为基础,再加上新的内容即可,以减少重复的工作量。C+提供的继承机制就是为了解决这个问题。,在C+中所谓“继承”就是在一个已存在的类的基础上建立一个新的类。已存在的类称为“基类(baseclass)”或“父类(fatherclass)”。新建立的类称为“派生类(derivedclass)”或“子类(sonclass)”。,.,50,classStudent1:publicStudent/声明基类是Studentprivate:intage;/新增加的数据成员stringaddr;/新增加的数据成员public:voiddisplay_1()/新增加的成员函数coutage:ageendl;coutaddress:addrendl;,.,51,类A派生类B:类A为基类,类B为派生类。,A,B,新增加的成员数据和成员函数,.,52,基类与派生类,被继承的类叫基类(baseclass)或父类,继承后产生的类叫派生类(derivedclass)或子类拥有自己的新数据和成员函数,还可以拥有父类的数据成员和成员函数。任何类都可以成为基类,一个基类可以有多个派生类,一个派生类还可以成为其他类的基类。,class派生类名:继承方式基类名派生类新增的数据成员;派生类新增的成员函数;,规定如访问基类的成员,可以有private,public,protected,.,53,classpersonprivate:charname10;charsex3;intage;public:voidinit(char*str1,char*str2,intk)/定义初始化成员函数strcpy(name,str1);strcpy(sex,str2);age=k;voiddisp()/定义输出成员函数coutname:nameendl;coutsex:sexendl;coutage:ageendl;,classstudent:publicperson/派生类的定义private:charsclass11;intnum;floatavg;public:voidinit_stud(char*str,inti,floatj)strcpy(sclass,str);num=i;avg=j;voiddisp_stud()coutclass:sclassendl;coutnum:numendl;coutavg:avgendl;,.,54,公有派生classClassName:publicBaseClassName公有派生时,基类中所有成员在派生类中保持各个成员的访问权限。,公有派生,派生类中保持基类的成员特性,基类:public:在派生类和类外可以使用protected:在派生类中使用private:不能在派生类中使用,.,55,classAintx;protected:inty;public:intz;A(inta,intb,intc)x=a;y=b;z=c;/基类初始化intGetx()returnx;/返回xintGety()returny;/返回yvoidShowA()coutx=xty=ytz=zn;classB:publicAintm,n;public:B(inta,intb,intc,intd,inte):A(a,b,c)m=d;n=e;voidShow()cout“m=mt“n=nn;coutx=Getx()ty=ytz=zn;intSum()return(Getx()+y+z+m+n);voidmain(void)Bb1(1,2,3,4,5);b1.ShowA();b1.Show();coutSum=b1.Sum()n;coutx=b1.Getx()t;couty=b1.Gety()t;coutz=b1.zn;,公有派生,对基类初始化,因为x是基类私有,所以在派生类和类外不能直接引用,因为y是基类保护,所以在派生类中可以直接引用。而在类外不可直接引用。,因为z是基类公有,所以在派生类中和类外均可直接引用。,.,56,私有派生classClassName:privateBaseClassName私有派生时,基类中公有成员和保护成员在派生类中均变为私有的,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。,私有派生,派生类中基类公有和保护成员成为私有,基类:public:(变为私有)在派生类中使用,类外不可使用protected:(变为私有)在派生类中使用,类外不可使用private:不能在派生类中和类外使用,.,57,classAintx;/私有继承.cppprotected:inty;public:intz;A(inta,intb,intc)x=a;y=b;z=c;/基类初始化intGetx()returnx;/返回xintGety()returny;/返回yvoidShowA()coutx=xty=ytz=zn;classB:privateAintm,n;public:B(inta,intb,intc,intd,inte):A(a,b,c)m=d;n=e;voidShow()cout“m=mt“n=nn;coutx=Getx()ty=ytz=zn;/ShowA();intSum()return(Getx()+y+z+m+n);voidmain(void)Bb1(1,2,3,4,5);b1.ShowA();b1.Show();coutSum=b1.Sum()n;coutx=b1.Getx()t;couty=b1.Gety()t;coutz=b1.zn;,私有派生,对基类初始化,因为x是基类私有,所以在派生类和类外不能直接引用,y是基类保护,所以在派生类中可以直接引用。而在类外不可直接引用。,.,58,保护派生classClassName:protectedBaseClassName保护派生时,基类中公有成员和保护成员在派生类中均变为保护的和私有的,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。,保护派生,派生类中基类公有和保护成员降级使用,基类:public:(变为保护)在派生类中使用,类外不可使用protected:(变为私有)在派生类中使用,类外不可使用private:不能在派生类中和类外使用,.,59,多重继承,A,B,C,多重继承是单一继承的扩展,派生类中新定义的成员,可以用多个基类来派生一个类。,.,60,格式为:class类名:类名1,.,类名nprivate:.;/私有成员说明;public:.;/公有成员说明;protected:.;/保护的成员说明;,继承方式,classD:publicA,protectedB,privateC./派生类中新增加成员;,.,61,classAintx1,y1;public:A(inta,intb)x1=a;y1=b;voidShowA(void)coutA.x=x1tA.y=y1endl;classBintx2,y2;public:B(inta,intb)x2=a;y2=b;voidShowB(void)coutB.x=x2tB.y=y2endl;classC:publicA,privateBintx,y;public:C(inta,intb,intc,intd,inte,intf):A(a,b),B(c,d)x=e;y=f;voidShowC(void)coutC.x=xtC.y=yendl;ShowA();ShowB();voidmain(void)Cc(1,2,3,4,5,6);c.ShowC();c.ShowA();c.ShowB();,公有派生,私有派生,仍为公有,成为私有,非法,私有成员类外不可调用,Bb1(10,20);b1.ShowB();,.,62,初始化基类成员,构造函数不能被继承,派生类的构造函数必须调用基类的构造函数来初始化基类成员基类子对象。,派生类构造函数的调用顺序如下:基类的构造函数子对象类的构造函数派生类的构造函数,.,63,classB:publicAinty;Aa1;public:B(inta,intb):A(a),a1(3)y=b;.;,当撤销派生类对象时,析构函数的调用正好相反。,基类的构造函数子对象类的构造函数派生类的构造函数,.,64,【举例】有三个基类Base1、Base2和Base3。Base1、Base2的构造函数带有参数,Base3有一个不带参数的构造函数。类Derive由这三个基类经过公有派生而来。Derive新增加了三个私有对象成员memberBase1、memberBase2和memberBase3,它们分别是Base1、Base2和Base3类的对象。派生类没有定义(即采用默认的)析构函数。程序代码如下:,.,65,/派生构造.cpp:演示继承与派生的构造函数和析构函数#includeclassBase1/基类Base1,构造函数有参数public:Base1(inti)coutconstructingBase1iendl;Base1()coutdestructingBase1endl;,classBase2/基类Base2,构造函数有参数public:Base2(intj)coutconstructingBase2jendl;Base2()coutdestructingBase2endl;,classBase3/基类Base3,构造函数无参数public:Base3()coutconstructingBase3endl;Base3()coutdestructingBase3endl;,.,66,/派生新类:classDerive:publicBase2,publicBase1,publicBase3private:/派生类新增私有对象成员Base1memberBase1;Base2memberBase2;Base3memberBase3;public:/派生类的构造函数Derive(inta,intb,intc,intd):Base1(a),memberBase2(d),memberBase1(c),Base2(b);voidmain()Deriveobject(2,4,6,8);,列出所有需要使用参数进行初始化的基类名字和所有对象成员的名字及各自的参数列表,对于使用默认构造函数的基类或对象成员,可以不给出类名或对象名及参数,.,67,程序运行结果为:constructingBase24constructingBase12constructingBase3constructingBase16constructingBase28constructingBase3destructingBase3destructingBase2destructingBase1destructingBase3destructingBase1destructingBase2,.,68,冲突,A,B,C,Dv;,v.x=5;,public,派生类对象,产生了冲突,v.A:x=5;,用类作用符限定,.,69,classApublic:intx;voidShow()coutx=xn;A(inta=0)x=a;classBpublic:intx;voidShow()coutx=xn;B(inta=0)x=a;classC:publicA,publicBinty;public:voidSetx(inta)x=a;/c1对象中有两个x成员voidSety(intb)y=b;intGety()returny;voidmain(void)Cc1;c1.Show();/c1对象中有两个Show()函数,这时,可以利用类作用域符:来指明数据或函数的来源。如:A:x=a;c1.B:Show();,.,70,支配规则,A,D,public,基类成员,派生类新增成员,Dv;,v.x=5;,当派生类中新增加的数据或函数与基类中原有的同名时,若不加限制,则优先调用派生类中的成员。,5,.,71,classApublic:intx;voidShow()coutx=xn;classBpublic:inty;voidShow()couty=yn;classC:publicA,publicBpublic:inty;/类B和类C均有y的成员;voidmain(void)Cc1;c1.x=100;c1.y=200;/给派生类中的y赋值c1.B:y=300;/给基类B中的y赋值c1.A:Show();c1.B:Show();/用作用域运算符限定调用的函数couty=c1.yn;/输出派生类中的y值couty=c1.B:yn;/输出基类B中的y值,当派生类中新增加的数据或函数与基类中原有的同名时,若不加限制,则优先调用派生类中的成员。,.,72,虚基类,类B是类A的派生类,A类,B类,C类,D类,类A拷贝,类C是类A的派生类,类D是类B和类C的派生类,这样,类D中就有两份类A的拷贝,B类,C类,类A拷贝,.,73,这种同一个公共的基类在派生类中产生多个拷贝,不仅多占用了存储空间,而且可能会造成多个拷贝中的数据不一致和模糊的引用。,Dd;d.x=10;/模糊引用,.,74,classApublic:intx;A(inta=0)x=a;classB:publicApublic:inty;B(inta=0,intb=0):A(a)y=b;classC:publicApublic:intz;C(inta,intc):A(a)z=c;classD:publicB,publicCpublic:intdx;D(inta1,intb,intc,intd,inta2):B(a1,b),C(a2,c)dx=d;voidmain(void)Dd1(10,20,30,40,50);coutd1.xendl;,dx,D(),x,A(),z,C(),y,B(),A(),x,D类,a1=10,b=20,a2=50,c=30,dx=40,模糊引用,错误!,d1.B:x或d1.C:x,.,75,在多重派生的过程中,要使公共基类在派生类中只有一个拷贝,则可将这种基类说明为虚基类。,classB:publicvirtualApublic:inty;B(inta=0,intb=0):A(b)y=a;,在派生类的定义中,只要在基类的类名前加上关键字virtual,就可以将基类说明为虚基类。,.,76,A类,B类,C类,D类,一份拷贝,在D()的构造函数中直接调用A(),由虚基类派生出的对象初始化时,直接调用虚基类的构造函数。因此,若将一个类定义为虚基类,则一定有正确的构造函数可供所有派生类调用。,.,77,classApublic:intx;A(inta=0)x=a;classB:publicvirtualApublic:inty;B(inta=0,intb=0):A(a)y=b;classC:publicvirtualApublic:intz;C(inta=0,intc=0):A(a)z=c;classD:publicB,publicCpublic:intdx;D(inta1,intb,intc,intd,inta2):B(a1,b),C(a2,c)dx=d;,voidmain(void)Dd1(10,20,30,40,50);coutd1.xendl;d1.x=400;coutd1.xendl;coutd1.yShow(),基类指针,派生类对象,基类对象,.,81,classPointfloatx,y;public:Point()Point(floati,floatj)x=i;y=j;floatarea(void)return0.0;constfloatPi=3.14159;classCircle:publicPoint/类Point的派生类floatradius;public:Circle(floatr)radius=r;floatarea(void)returnPi*radius*radius;voidmain(void)Point*pp;/基类指针,可以将派生类对象的地址赋给基类指针Circlec(5.4321);pp=/调用的是基类中有的公有函数,在基类和派生类中具有相同的公有函数area()。,在这种情况下,使用基类的指针时,只能访问从相应基类中继承来的成员,而不允许访问在派生类中增加的成员。输出为0,.,82,基类对象,派生类对象,Baseb;,Derived;,basep,basep,basep-Show(),Base*basep;,basep=,basep=,basep-Show();,要指向派生类新增的成员函数,需要将基类中的Show()说明为虚函数,.,83,若要访问派生类中相同名字的函数,必须将基类中的同名函数定义为虚函数,这样,将不同的派生类对象的地址赋给基类的指针变量后,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论