C程序设计教程与实验指导杨国兴多态性.pptx

上传人:莉*** 文档编号:87577309 上传时间:2023-04-16 格式:PPTX 页数:46 大小:243.92KB
返回 下载 相关 举报
C程序设计教程与实验指导杨国兴多态性.pptx_第1页
第1页 / 共46页
C程序设计教程与实验指导杨国兴多态性.pptx_第2页
第2页 / 共46页
点击查看更多>>
资源描述

《C程序设计教程与实验指导杨国兴多态性.pptx》由会员分享,可在线阅读,更多相关《C程序设计教程与实验指导杨国兴多态性.pptx(46页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第第6章章 多态性多态性6.1运算符重载6.2运算符重载为类的成员函数6.3运算符重载为类的友元函数6.4虚函数第1页/共46页6.1 6.1 运算符重载运算符重载6.1.1问题的提出例的复数类例的复数类#include#include class CComplex class CComplex private:private:double real;double real;double imag;double imag;public:public:CComplex(double r,double i);CComplex(double r,double i);void Print();void

2、 Print();CComplex Add(CComplex c);CComplex Add(CComplex c);CComplex Sub(CComplex c);CComplex Sub(CComplex c);第6章 多态性CComplex CComplex:Add(CComplex CComplex CComplex:Add(CComplex c)c)CComplex temp;CComplex temp;=real+;=real+;=imag+;=imag+;return temp;return temp;CComplex CComplex:Sub(CComplex CComple

3、x CComplex:Sub(CComplex c)c)CComplex temp;CComplex temp;=real-;=real-;=imag-;=imag-;return temp;return temp;第2页/共46页6.1 6.1 运算符重载运算符重载6.1.1问题的提出(续一)void main(void)void main(void)CComplex a(1,2),b(3.0,4.0),c,d;CComplex a(1,2),b(3.0,4.0),c,d;c=a.Add(b);c=a.Add(b);d=a.Sub(b);d=a.Sub(b);cout c=;cout c=;

4、();();cout d=;cout d=;();();第6章 多态性复数加减法只能调用成员函数实现,不能使用符号“+”和“-”,可以通过重载“+”、“-”运算符,实现如c=a+b这样的调用方式运算符重载:运算符重载的实质就是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时,产生不同的行为。运算符重载的实质就是函数重载。第3页/共46页例6.1 用运算符实现复数的加减运算#include iostreamusing namespace std;class CComplex private:double real;double imag;public:CComplex(doubl

5、e r=0,double i=0);void Print();CComplex operator+(CComplex c);CComplex operator-(CComplex c);CComplex:CComplex(double r,double i)real=r;imag=i;第6章 多态性第4页/共46页例6.1 (续一)void CComplex:Print()cout (real ,imag )endl;CComplex CComplex:operator+(CComplex c)CComplex temp;=real+;=imag+;return temp;CComplex C

6、Complex:operator-(CComplex c)CComplex temp;=real-;=imag-;return temp;第6章 多态性第5页/共46页例6.1 (续二)void main(void)CComplex a(1,2),b(3.0,4.0),c,d;c=a+b;d=a-b;cout c=;();cout d=;();第6章 多态性该语句相当于对函数operator+(CComplex c)的调用:“c=+(b)”,实现两个复数的加法运算。程序运行结果为:程序运行结果为:c=(4,6)c=(4,6)d=(-2,-2)d=(-2,-2)第6页/共46页6.1 6.1 运

7、算符重载运算符重载6.1.2运算符重载的格式与规则1.1.运算符重载的格式运算符重载的格式运算符重载的格式运算符重载的格式 运算符重载为类的成员函数运算符重载为类的成员函数 运算符重载为类的友元函数运算符重载为类的友元函数 运算符重载的为类的成员函数,在类中声明的格式为:运算符重载的为类的成员函数,在类中声明的格式为:运算符重载的为类的成员函数,在类中声明的格式为:运算符重载的为类的成员函数,在类中声明的格式为:函数类型函数类型 operatoroperator运算符(参数表);运算符(参数表);定义该函数的格式:定义该函数的格式:定义该函数的格式:定义该函数的格式:函数类型函数类型 类名类名

8、:operator:operator运算符(参数表)运算符(参数表)函数体;函数体;也可以将重载运算符函数的定义直接写在类中。也可以将重载运算符函数的定义直接写在类中。第6章 多态性第7页/共46页6.1 6.1 运算符重载运算符重载6.1.2运算符重载的格式与规则(续)2.2.运算符重载的规则运算符重载的规则运算符重载的规则运算符重载的规则(1 1)除)除“.”.”、“*”“*”、“:”:”、“?:”?:”和和“sizeof”sizeof”等几个等几个运算符不能重载外,运算符不能重载外,C+C+中几乎所有的运算符都可以重载。中几乎所有的运算符都可以重载。(2 2)运算符被重载后,其优先级和结

9、合性不会改变。)运算符被重载后,其优先级和结合性不会改变。(3 3)不能改变运算符操作对象的个数。)不能改变运算符操作对象的个数。第6章 多态性 返 回第8页/共46页6.2 6.2 运算符重载为类的成员函数运算符重载为类的成员函数6.2.1双目运算符重载双目运算符双目运算符,如果,如果重载为类的成员函数重载为类的成员函数,其,其参数为一个参数为一个,即比运算对象少一个。即比运算对象少一个。例例6.26.2复数的乘法运算,在上例的基础上添加乘法运算复数的乘法运算,在上例的基础上添加乘法运算符重载函数。复数类乘法运算的定义如下:符重载函数。复数类乘法运算的定义如下:(a+bia+bi)*(x+y

10、ix+yi)=a*x-b*y+(a*y+b*x)i=a*x-b*y+(a*y+b*x)i第6章 多态性第9页/共46页例6.2 复数乘法运算源程序#include iostreamusing namespace std;class CComplex private:double real;double imag;public:CComplex(double r=0,double i=0);void Print();CComplex operator+(CComplex c);CComplex operator-(CComplex c);CComplex operator*(CComplex c

11、);CComplex:CComplex(double r,double i)real=r;imag=i;第6章 多态性第10页/共46页例6.2 (续一)void CComplex:Print()cout (real ,imag )endl;CComplex CComplex:operator+(CComplex c)CComplex temp;=real+;=imag+;return temp;CComplex CComplex:operator-(CComplex c)CComplex temp;=real-;=imag-;return temp;第6章 多态性第11页/共46页例6.2

12、(续二)CComplex CComplex:operator*(CComplex c)CComplex temp;=real*-imag*;=real*+imag*;return temp;void main(void)CComplex a(1,2),b(3.0,4.0),c,d,e,f;c=a+b;d=a-b;e=a*b;f=a+1;cout c=;();cout d=;();cout e=;();cout f=;();第6章 多态性程序运行结果为:程序运行结果为:c=(4,6)c=(4,6)d=(-2,-2)d=(-2,-2)e=(-5,10)e=(-5,10)f=(2,2)f=(2,2)

13、总结:总结:设有双目运算符设有双目运算符 B B,如果要重,如果要重载载 B B 为类的成员函数,使之能够实为类的成员函数,使之能够实现表达式现表达式 oprd1 B oprd2oprd1 B oprd2,其中,其中 oprd1 oprd1 为为A A 类对象,则类对象,则 B B 应被重载应被重载为为 A A 类的成员函数,形参类型应该类的成员函数,形参类型应该是是 oprd2 oprd2 所属的类型。所属的类型。经重载后,表达式经重载后,表达式oprd1 B oprd1 B oprd2 oprd2 相当于相当于 oprd1.operator oprd1.operator B(oprd2)B

14、(oprd2),注意重载双目运算符只,注意重载双目运算符只需要一个参数。需要一个参数。第12页/共46页6.2 6.2 运算符重载为类的成员函数运算符重载为类的成员函数6.2.2单目运算符重载单目运算符单目运算符,如果,如果重载为类的成员函数重载为类的成员函数,不需要参数不需要参数。为区分前置和后置运算符,为区分前置和后置运算符,C+C+规定:规定:对于对于前置单目运算符前置单目运算符,重载函数,重载函数没有参数没有参数对于对于后置单目运算符后置单目运算符,重载函数,重载函数有一个整型参数有一个整型参数,这个整,这个整型参数没有其他用途,只是用于区分前置运算与后置运算。型参数没有其他用途,只是

15、用于区分前置运算与后置运算。第6章 多态性第13页/共46页例6.3 定义一个CInt类,类中只有一个数据成员i,两个运算符“+”的重载函数,一个没有参数,实现的是前置运算符重载,另一个有一个整型参数,实现后置运算符重载。#include iostreamusing namespace std;class CInt private:int i;public:CInt(int a=0);void Print();CInt operator+();CInt operator+(int);CInt:CInt(int a)i=a;第6章 多态性voidCInt:Print()voidCInt:Prin

16、t()couti=iendl;couti=iendl;CIntCInt:operator+()CIntCInt:operator+()CInttemp;CInttemp;=+i;=+i;returntemp;returntemp;CIntCInt:operator+(int)CIntCInt:operator+(int)CInttemp;CInttemp;=i+;=i+;returntemp;returntemp;第14页/共46页例6.3 (续)void main(void)CInt a(5),b(5),c,d;c=a+;d=+b;cout a:;();cout b:;();cout c:;

17、();cout d:;();第6章 多态性程序运行结果为:程序运行结果为:a:i=6a:i=6b:i=6b:i=6c:i=5c:i=5d:i=6d:i=6第15页/共46页6.2 6.2 运算符重载为类的成员函数运算符重载为类的成员函数6.2.3赋值运算符重载如果类中只包含简单数据类型的数据成员,则使用如果类中只包含简单数据类型的数据成员,则使用C+C+提提供的赋值运算符供的赋值运算符“=”=”就可以实现将一个对象赋给另一个对象。就可以实现将一个对象赋给另一个对象。如前面复数类的对象,就可以将一个对象直接赋给另一个对象。如前面复数类的对象,就可以将一个对象直接赋给另一个对象。但如果类的数据成员

18、比较复杂(如含有指针),这样直接赋值但如果类的数据成员比较复杂(如含有指针),这样直接赋值就会产生问题,我们必须重载赋值运算符就会产生问题,我们必须重载赋值运算符“=”=”才能正确使用才能正确使用“=”=”。第6章 多态性第16页/共46页例6.4 类A只有一个数据成员str,是一个字符指针,在构造函数中为str申请存储空间并赋值,在析构函数中释放内存。#include iostream#include stringusing namespace std;class A private:char*str;public:A(char*s=no data);A();void print();A:A

19、(char*s)int len=strlen(s);str=new charlen+1;strcpy(str,s);第6章 多态性第17页/共46页例6.4 (续)A:A()if(str)delete str;void A:print()cout str endl;void main(void)A*p=new A(AAAA);A a1;a1=*p;a1.print();delete p;a1.print();第6章 多态性strpstra1AAAA该语句只是将p所指向的对象数据成员str赋给对象a1的数据成员str,即两个对象的str指向了同一个单元调用析构函数,同时将str所指向的单元释放了

20、,再执行a1.print()时,就会出现错误。第18页/共46页例6.5 带有重载赋值运算符的A类#include iostream#include stringusing namespace std;class A private:char*str;public:A(char*s=no data);A();A&operator=(A&a);void print();A:A(char*s)int len=strlen(s);str=new charlen+1;strcpy(str,s);第6章 多态性第19页/共46页例6.5 (续一)A:A()if(str)delete str;A&A:op

21、erator=(A&a)int len=);if(str)delete str;/先释放,再根据实际需要重新申请str=new charlen+1;strcpy(str,);return*this;void A:print()cout str endl;第6章 多态性第20页/共46页例6.5 (续二)void main(void)A*p=new A(AAAA);A a1;a1=*p;a1.print();delete p;a1.print();第6章 多态性strpstra1AAAAAAAA程序运行结果为:程序运行结果为:AAAAAAAAAAAAAAAA 返 回第21页/共46页6.3 6.

22、3 运算符重载为类的友元函数运算符重载为类的友元函数6.3.1问题的提出(1 1)复数与复数相加()复数与复数相加(c1c1,c2c2,c3c3是复数类的对象)。是复数类的对象)。c3=c1+c2c3=c1+c2;(2 2)一个复数与一个实数的加法运算)一个复数与一个实数的加法运算;(3 3)一个实数与一个复数相加就会出现错误。)一个实数与一个复数相加就会出现错误。c3=c3=10.8+c110.8+c1;因为加号左边的运算对象是实数,因为加号左边的运算对象是实数,C+C+试图将加号右边的试图将加号右边的运算对象解释为实数,但运算对象解释为实数,但C+C+无法将一个复数转换为一个实数,无法将一

23、个复数转换为一个实数,从而产生错误。从而产生错误。将运算符重载为友元函数可以解决这个问题。将运算符重载为友元函数可以解决这个问题。第6章 多态性第22页/共46页6.3 6.3 运算符重载为类的友元函数运算符重载为类的友元函数6.3.2运算符重载为友元函数 类中的类中的声明声明:friendfriend函数类型函数类型 operatoroperator运算符(参数表);运算符(参数表);运算符重载函数的运算符重载函数的定义形式定义形式:函数类型函数类型 operatoroperator运算符(参数表)运算符(参数表)函数体;函数体;第6章 多态性第23页/共46页例6.6 用友元函数实现复数类

24、加减运算符的重载#include iostreamusing namespace std;class CComplex private:double real;double imag;public:CComplex(double r=0,double i=0);void Print();friend CComplex operator+(CComplex c1,CComplex c2);friend CComplex operator-(CComplex c1,CComplex c2);CComplex:CComplex(double r,double i)real=r;imag=i;第6章

25、多态性第24页/共46页例6.6 (续一)void CComplex:Print()cout (real ,imag )endl;CComplex operator+(CComplex c1,CComplex c2)CComplex temp;=c1.real+c2.real;=c1.imag+c2.imag;return temp;CComplex operator-(CComplex c1,CComplex c2)CComplex temp;=c1.real-c2.real;=c1.imag-c2.imag;return temp;第6章 多态性第25页/共46页例6.6 (续二)void

26、 main(void)CComplex a(1,2),b(3.0,4.0),c,d,e;c=a+b;d=b-10;e=20+a;cout c=;();cout d=;();cout e=;();第6章 多态性相当于函数调用“c=operator+(a,b)”程序运行结果为:程序运行结果为:c=c=(4,64,6)d=d=(-7,4-7,4)e=e=(21,221,2)总结:总结:设有双目运算符设有双目运算符 B B,如果要重,如果要重载载 B B 为类的友元函数,则该友元函为类的友元函数,则该友元函数也有两个参数,分别为运算符的两数也有两个参数,分别为运算符的两个运算对象。重载后,表达式个运算

27、对象。重载后,表达式oprd1 oprd1 B oprd2 B oprd2 等同于调用函数等同于调用函数operator operator B(oprd1,oprd2)B(oprd1,oprd2)。单目运算符也可以重载为类的友元函数,该友元函数有一个参数。返 回第26页/共46页6.4 6.4 虚函数虚函数6.4.1用虚函数实现动态多态回顾例回顾例voidmain()voidmain()CShape*ps3;CShape*ps3;CShapes(Red);CShapes(Red);CPointp1(10,10),p2(100,100),p3(50,50);CPointp1(10,10),p2(

28、100,100),p3(50,50);CLinel(p1,p2,Green);CLinel(p1,p2,Green);CCirclec(p3,20,Black);CCirclec(p3,20,Black);ps0=&s;ps0=&s;ps1=&l;ps1=&l;ps2=&c;ps2=&c;for(inti=0;i3;i+)for(inti=0;iDraw();psi-Draw();第6章 多态性程序运行结果为:程序运行结果为:DrawaShape.ThecolorisRedDrawaShape.ThecolorisRedDrawaShape.ThecolorisGreenDrawaShape.

29、ThecolorisGreenDrawaShape.ThecolorisRedBlackDrawaShape.ThecolorisRedBlack虽然父类的指针可以指向子类的对象,但调用的函数Draw()都是父类CShape的成员函数 为了能通过基类的指针调用派生类的成员函数,可以使用虚函数的方法,即把成员函数Draw()声明为虚函数。第27页/共46页例6.7 用虚函数实现动态多态#include#include using namespace std;class CPointprivate:int X;int Y;public:CPoint(int x=0,int y=0)X=x;Y=y;

30、CPoint(CPoint&p)X=;Y=;int GetX()return X;int GetY()return Y;第6章 多态性第28页/共46页例6.7 (续一)class CShapeprivate:char Color10;public:CShape(char*c)strcpy(Color,c);virtual void Draw()cout Draw a Shape.The color is Color endl;void PrintColor()cout Color endl;第6章 多态性第29页/共46页例6.7 (续二)class CLine:public CShapep

31、rivate:CPoint Start;CPoint End;public:CLine(CPoint s,CPoint e,char*c):CShape(c),Start(s),End(e)virtual void Draw()cout Draw a Line from(),();cout )to(),(),with color;PrintColor();第6章 多态性第30页/共46页例6.7 (续三)class CCircle:public CShapeprivate:CPoint Center;int Radius;public:CCircle(CPoint ctr,int r,char

32、*c):CShape(c),Center(ctr)Radius=r;virtual void Draw()cout Draw a Circle at center(),;cout ()with radius Radius and color;PrintColor();第6章 多态性第31页/共46页例6.7 (续四)void main()CShape*ps3;CShape s(Red);CPoint p1(10,10),p2(100,100),p3(50,50);CLine l(p1,p2,Green);CCircle c(p3,20,Black);ps0=&s;ps1=&l;ps2=&c;f

33、or(int i=0;iDraw();第6章 多态性程序运行结果为:程序运行结果为:DrawaShape.ThecolorisRedDrawaShape.ThecolorisRedDrawaLinefrom(10,10)to(100,100),withcolorGreenDrawaLinefrom(10,10)to(100,100),withcolorGreenDrawaCircleatcenter(50,50)withradius20andcolorBlackDrawaCircleatcenter(50,50)withradius20andcolorBlack第32页/共46页6.4 6.4

34、 虚函数虚函数6.4.16.4.1用虚函数实现动态多态(续)用虚函数实现动态多态(续)总结:总结:(1 1)将成员函数声明为)将成员函数声明为虚函数虚函数,在函数原型前加关键字,在函数原型前加关键字virtualvirtual,如果成员函数的定义直接写在类中,也在前面加关键,如果成员函数的定义直接写在类中,也在前面加关键字字virtualvirtual。(2 2)将成员函数声明为虚函数后,再将基类指针指向派生)将成员函数声明为虚函数后,再将基类指针指向派生类对象,在程序运行时,就会根据指针指向的具体对象来调用类对象,在程序运行时,就会根据指针指向的具体对象来调用各自的虚函数,称之为各自的虚函数

35、,称之为动态多态动态多态。(3 3)如果基类的成员函数是虚函数,)如果基类的成员函数是虚函数,在其派生类中,原型在其派生类中,原型相同的函数自动成为虚函数相同的函数自动成为虚函数。第6章 多态性第33页/共46页6.4 6.4 虚函数虚函数6.4.26.4.2用虚函数实现动态多态的机制用虚函数实现动态多态的机制为了实现为了实现动态多态动态多态,编译器对每个包含虚函数的类创建一,编译器对每个包含虚函数的类创建一个个虚函数地址虚函数地址表表表表,并设置一个,并设置一个虚函数地址指针虚函数地址指针指向这个对象的指向这个对象的虚函数地址表。使用基类指针对虚函数调用时,通过这个虚函虚函数地址表。使用基类

36、指针对虚函数调用时,通过这个虚函数地址指针,在虚函数地址表中查找函数地址。数地址指针,在虚函数地址表中查找函数地址。由于由于包含虚函数的类包含虚函数的类,有一个虚函数地址指针,与没有虚,有一个虚函数地址指针,与没有虚函数的类相比,含有虚函数类的对象所占用的函数的类相比,含有虚函数类的对象所占用的存储空间要多一存储空间要多一个指针所占用的内存个指针所占用的内存。第6章 多态性第34页/共46页例6.8 含有虚函数类的对象所占用的存储空间。#include using namespace std;class Aprivate:int a;public:virtual void func();cla

37、ss B:public A private:int b;public:virtual void func()virtual void func1();void main(void)cout sizeof(A)=sizeof(A)endl;cout sizeof(B)=sizeof(B)endl;第6章 多态性程序运行结果为:程序运行结果为:sizeof(A)=8sizeof(A)=8sizeof(B)=12sizeof(B)=12第35页/共46页6.4 6.4 虚函数虚函数6.4.26.4.2用虚函数实现动态多态的机制(续)用虚函数实现动态多态的机制(续)每个每个含有虚函数类的对象含有虚函数

38、类的对象都有一个都有一个虚函数地址指针虚函数地址指针,指向,指向该类虚函数表,如果用基类的指针调用虚函数,在编译时,并该类虚函数表,如果用基类的指针调用虚函数,在编译时,并不能确定这个指针的具体指向,而是在运行时,不能确定这个指针的具体指向,而是在运行时,根据指针所指根据指针所指向的具体对象向的具体对象(基类的对象或其派生类的对象),(基类的对象或其派生类的对象),虚函数地址虚函数地址指针才有一个确定的值指针才有一个确定的值,即相应类的这个虚函数的地址。从而,即相应类的这个虚函数的地址。从而实现动态多态。实现动态多态。第6章 多态性第36页/共46页6.4 6.4 虚函数虚函数6.4.36.4

39、.3虚析构函数虚析构函数析构函数也可以定义为虚函数,如果基类的析构函数定义析构函数也可以定义为虚函数,如果基类的析构函数定义为虚析构函数,则派生类的析构函数就会自动成为虚析构函数。为虚析构函数,则派生类的析构函数就会自动成为虚析构函数。如果如果基类的指针指向派生类对象基类的指针指向派生类对象,当用,当用deletedelete删除这个对删除这个对象时,若析构函数不是虚函数,就要象时,若析构函数不是虚函数,就要调用基类的析构函数调用基类的析构函数,而,而不会调用派生类的析构函数不会调用派生类的析构函数。如果为基类和派生类的对象分配。如果为基类和派生类的对象分配了动态内存,或者为派生类的对象成员分

40、配了动态内存,这时了动态内存,或者为派生类的对象成员分配了动态内存,这时释放的只是基类中动态分配的内存,而派生类中动态分配的内释放的只是基类中动态分配的内存,而派生类中动态分配的内存未被释放,因此存未被释放,因此一般应将析构函数定义为虚析构函数一般应将析构函数定义为虚析构函数。第6章 多态性第37页/共46页例 定义职员类CEmployee,数据成员有姓名(字符指针型数据)和年龄,由CEmployee类派生出教师类CTeacher,增加数据成员教学简历(字符指针型数据)。#include#include using namespace std;class CEmployeeprivate:ch

41、ar*name;int age;public:CEmployee(char*n,int a);virtual CEmployee();CEmployee:CEmployee(char*n,int a)name=new charstrlen(n)+1;strcpy(name,n);age=a;第6章 多态性第38页/共46页例 (续一)CEmployee:CEmployee()cout Destruct CEmployee endl;if(name)delete name;class CTeacher:public CEmployee private:char*mainCourse;public

42、:CTeacher(char*n,char*course,int a);virtual CTeacher();/由于基类已定义虚析构函数,此处也可不加virtual;CTeacher:CTeacher(char*n,char*course,int a):CEmployee(n,a)mainCourse=new charstrlen(course)+1;strcpy(mainCourse,course);第6章 多态性第39页/共46页例 (续二)CTeacher:CTeacher()cout Destruct CTeacher endl;if(mainCourse)delete mainCou

43、rse;void main(void)CEmployee*p3;p0=new CEmployee(Name1,20);p1=new CTeacher(Name2,C for 2 years,C+3 years,26);p2=new CTeacher(Name3,Data structure for 2 years,C+3 years,30);for(int i=0;i3;i+)delete pi;第6章 多态性程序运行结果为:程序运行结果为:DestructCEmployeeDestructCEmployeeDestructCTeacherDestructCTeacherDestructCEm

44、ployeeDestructCEmployeeDestructCTeacherDestructCTeacherDestructCEmployeeDestructCEmployee若不定义为虚析构函数,程序运行结果为:若不定义为虚析构函数,程序运行结果为:DestructCEmployeeDestructCEmployeeDestructCEmployeeDestructCEmployeeDestructCEmployeeDestructCEmployee由于未调用CTeacher类析构函数,导致成员mainCourse空间未被释放第40页/共46页6.4 6.4 虚函数虚函数6.4.46.4.

45、4纯虚函数与抽象类纯虚函数与抽象类 纯虚函数纯虚函数是不必定义函数体的特殊虚函数,纯虚函数的是不必定义函数体的特殊虚函数,纯虚函数的声明格式为:声明格式为:virtualvirtual函数类型函数类型 函数名(参数表)函数名(参数表)=0=0;含有含有纯虚函数纯虚函数的类称为的类称为抽象类抽象类。抽象类常常用作派生类。抽象类常常用作派生类的基类。的基类。如果派生类继承了抽象类的纯虚函数,却没有重新定义原如果派生类继承了抽象类的纯虚函数,却没有重新定义原型相同且带函数体的虚函数,或者派生类定义了基类所没有定型相同且带函数体的虚函数,或者派生类定义了基类所没有定义的纯虚函数,则派生类仍然是抽象类,

46、在多层派生的过程中,义的纯虚函数,则派生类仍然是抽象类,在多层派生的过程中,如果到某个派生类为止,如果到某个派生类为止,所有纯虚函数都已全部重新定义,则所有纯虚函数都已全部重新定义,则该派生类就成为非抽象类该派生类就成为非抽象类。不能定义抽象类的对象,但可以声明抽象类的指针和引用不能定义抽象类的对象,但可以声明抽象类的指针和引用。第6章 多态性第41页/共46页例6.10 将例题中CShape类的函数Draw()声明为纯虚函数,其它类保持不变。class CShapeprivate:char Color10;public:CShape(char*c)strcpy(Color,c);virtua

47、l void Draw()0;void PrintColor()cout Color endl;第6章 多态性void main()void main()CShape*ps3;CShape*ps3;CPoint p1(10,10),CPoint p1(10,10),p2(100,100),p3(50,50);p2(100,100),p3(50,50);CLine l(p1,p2,Green);CLine l(p1,p2,Green);CCircle c(p3,20,Black);CCircle c(p3,20,Black);ps1=&l;ps1=&l;ps2=&c;ps2=&c;for(int

48、 i=1;i3;i+)for(int i=1;iDraw();psi-Draw();程序运行结果为:程序运行结果为:DrawaLinefrom(10,10)to(100,100),withcolorGreenDrawaLinefrom(10,10)to(100,100),withcolorGreenDrawaCircleatcenter(50,50)withradius20andcolorBlackDrawaCircleatcenter(50,50)withradius20andcolorBlack不能定义CShape类的对象,但可以定义CShape类的指针 返 回第42页/共46页6.5 6

49、.5 程序实例程序实例例例6.11 6.11 定义整数栈类定义整数栈类IntStackIntStack、顺序栈类、顺序栈类SeqStackSeqStack和链接栈类和链接栈类LinkStackLinkStack,其中整数栈类,其中整数栈类IntStackIntStack是一个抽象类,作为其他两个栈是一个抽象类,作为其他两个栈的基类。的基类。分析:分析:对于顺序栈类,进栈操作的方法是先将栈顶元素下标加对于顺序栈类,进栈操作的方法是先将栈顶元素下标加1 1,然后将进栈元素赋给栈顶。出栈操作的方法是,先取得栈顶元素值,然后将进栈元素赋给栈顶。出栈操作的方法是,先取得栈顶元素值,再将栈顶元素下标减再将

50、栈顶元素下标减1 1(注意:为简化程序,本实例未考虑栈满情(注意:为简化程序,本实例未考虑栈满情况的处理)。况的处理)。对于连接栈类,进栈操作的方法是先创建一个节点,将进栈对于连接栈类,进栈操作的方法是先创建一个节点,将进栈元素赋给新创建节点的数据域,再将新创建节点的元素赋给新创建节点的数据域,再将新创建节点的nextnext指针指向原指针指向原来的栈顶节点,然后将栈顶指针指向新创建的节点。出栈操作的方来的栈顶节点,然后将栈顶指针指向新创建的节点。出栈操作的方法是,先取得栈顶元素值,再将栈顶指针指向原来栈顶的下一个节法是,先取得栈顶元素值,再将栈顶指针指向原来栈顶的下一个节点。点。(具体代码参

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > PPT文档

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁