资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,第,9,章 虚函数与多态性,9.4,纯虚函数和抽象类,9.5.1,虚函数和多态性的应用,_,一个实例,2026/11/11,1,不用来定义对象而只作为一种基本类型用作继承的类称为抽象类,常用作基类,凡包含纯虚函数的类都是抽象类。,2026/11/11,2,9.4,纯虚函数和抽象类,纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本,纯虚函数为各派生类提供一个公共界面,纯虚函数说明形式:,virtual,类型,函数名,(,参数表,),=0,;,一个具有纯虚函数的基类称为抽象类。,2026/11/11,3,class point /*/;,class shape,;,/,抽象类,point center;,public:,point where()return center;,void move(point p)enter=p;draw();,virtual void rotate(,int,)=0;,/,纯虚函数,virtual void draw()=0;,/,纯虚函数,;,.,shape x;,/error,,,抽象类不能建立对象,shape *p;,/ok,,,可以声明抽象类的指针,shape f();,/error,抽象类不能作为返回类型,void g(shape);,/error,抽象类不能作为参数类型,shape ,/ok,,,可以声明抽象类的引用,例如:,2026/11/11,4,class point /*/;,class shape,;,/,抽象类,point center;,public:,point where()return center;,void move(point p)enter=p;draw();,virtual void rotate(,int,)=0;,/,纯虚函数,virtual void draw()=0;,/,纯虚函数,;,.,class,ab_circle,:,public shape,int,radius;,public:void rotate(,int,);,;,例如:,ab_circle,类仍为抽象类,ab_circle,:draw(),、,ab_circle,:rotate(),也是纯虚函数,要使,ab_circle,成为非抽象类,,必须作以下说明:,class,ab_circle,:public shape,int,radius;,public:,void rotate(,int,);,void draw();,;,并提供,ab_circle,:draw(),和,ab_circle,:rotate(,int,),的定义,2026/11/11,5,/figure.h,class figure,protected:double x,y;,public:void set_dim(double i,double j=0)x=i;y=j;,virtual void show_area()=0;,;,class triangle:public figure,public:,void show_area(),cout,Triangle with high x and base y has an area of x*0.5*yn;,;,class square:public figure,public:,void show_area(),cout,Square with dimension x*y has an area of x*yn;,;,class circle:public figure,public:,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,;,virtual void show_area()=0;,/,纯虚函数,简单图形类,void show_area(),cout,Triangle with high x and base y has an area of,x*0.5*yn;,void show_area(),cout,Square with dimension x*y has an area of,x*yn;,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,2026/11/11,6,/figure.h,class figure,protected:double x,y;,public:void set_dim(double i,double j=0)x=i;y=j;,virtual void show_area()=0;,;,class triangle:public figure,public:,void show_area(),cout,Triangle with high x and base y has an area of x*0.5*yn;,;,class square:public figure,public:,void show_area(),cout,Square with dimension x*y has an area of x*yn;,;,class circle:public figure,public:,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,;,virtual void show_area()=0;,/,纯虚函数,简单图形类,void show_area(),cout,Triangle with high x and base y has an area of,x*0.5*yn;,void show_area(),cout,Square with dimension x*y has an area of,x*yn;,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,#include,#includefigure.h,void main(),triangle t;,/,派生类对象,square s;,circle c;,t.set_dim(10.0,5.0);,t.show_area();,s.set_dim(10.0,5.0);,s.show_area();,c.set_dim(9.0);,c.show_area();,2026/11/11,7,/figure.h,class figure,protected:double x,y;,public:void set_dim(double i,double j=0)x=i;y=j;,virtual void show_area()=0;,;,class triangle:public figure,public:,void show_area(),cout,Triangle with high x and base y has an area of x*0.5*yn;,;,class square:public figure,public:,void show_area(),cout,Square with dimension x*y has an area of x*yn;,;,class circle:public figure,public:,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,;,virtual void show_area()=0;,/,纯虚函数,简单图形类,void show_area(),cout,Triangle with high x and base y has an area of,x*0.5*yn;,void show_area(),cout,Square with dimension x*y has an area of,x*yn;,void show_area(),cout,Circle with radius x;,cout,has an area of 3.14*x*xn;,#include,#includefigure.h,void main(),figure*p;,/,声明抽象类指针,triangle t;,square s;,circle c;,p=,p-set_dim(10.0,5.0);,/triangle:set_dim(),p-show_area();,p=,p-set_dim(10.0,5.0);,/square:set_dim(),p-show_area();,p=,p-set_dim(9.0);,/circle:set_dim(),p-show_area();,2026/11/11,8,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(Number&n),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),2026/11/11,9,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(,Number&n,),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),抽象类引用,2026/11/11,10,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(,Number&n,),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),函数调用,派生类对象,2026/11/11,11,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(,Number&n,),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),2026/11/11,12,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(,Number&n,),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),2026/11/11,13,#include,class Number,public:Number(,int,i),val,=i;,virtual void Show()=0;,protected:,int,val,;,;,class Hex_type:public Number,public:,Hex_type(int,i):Number(i),void Show(),cout,Hexadecimal:hex,val,endl,;,;,class Dec_type:public Number,public:,Dec_type(int,i):Number(i),void Show(),cout,Decimal:,dec,val,endl,;,;,class Oct_type:public Number,public:,Oct_type(int,i):Number(i),void Show(),cout,Octal:,oct,val,endl,;,;,使用抽象类引用,void fun(,Number&n,),/,抽象类的引用参数,n.Show();,void main(),Dec_type n1(50);,fun(n1);,/Dec_type:Show(),Hex_type n2(50);,fun(n2);,/Hex_type:Show(),Oct_type n3(50);,fun(n3);,/Oct_type:Show(),2026/11/11,14,虚函数和多态性使成员函数根据调用对象的类型产生不同的动作,多态性特别适合于实现分层结构的软件系统,便于对问题抽象时,定义共性,实现时定义区别,9.5,虚函数与多态的应用,2026/11/11,15,9.5.1,一个实例,计算雇员工资,Employee,HourWorker,Manager,PieceWorker,抽象类,提供一般属性,共同操作界面,管理人员类,提供特殊属性,操作实现,计时工人类,提供特殊属性,操作实现,计件工人类,提供特殊属性,操作实现,2026/11/11,16,/Employee.h,#,ifndef,EMPLOYEE_H,#define EMPLOYEE_H,class Employee,public:,Employee(const long,const char*);,virtual Employee();,const char*,getName,()const;,const long,getNumber,()const;,virtual double earnings()const=0;,virtual void print()const;,protected:,long number;,/,编号,char*name;,/,姓名,;,#,endif,Employee,HourWorker,Manager,PieceWorker,2026/11/11,17,/Employee.h,#,ifndef,EMPLOYEE_H,#define EMPLOYEE_H,class Employee,public:,Employee(const long,const char*);,virtual,Employee();,const char*,getName,()const;,const long,getNumber,()const;,virtual double earnings()const=0;,virtual void print()const;,protected:,long number;,/,编号,char*name;,/,姓名,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,虚析构函数,2026/11/11,18,/Employee.h,#,ifndef,EMPLOYEE_H,#define EMPLOYEE_H,class Employee,public:,Employee(const long,const char*);,virtual Employee();,const char*,getName,()const;,const long,getNumber,()const;,virtual,double earnings()const=0;,virtual void print()const;,protected:,long number;,/,编号,char*name;,/,姓名,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,虚析构函数,/,纯虚函数,计算月薪,2026/11/11,19,/Employee.h,#,ifndef,EMPLOYEE_H,#define EMPLOYEE_H,class Employee,public:,Employee(const long,const char*);,virtual Employee();,const char*,getName,()const;,const long,getNumber,()const;,virtual double earnings()const=0;,virtual,void print()const;,protected:,long number;,/,编号,char*name;,/,姓名,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,虚析构函数,/,纯虚函数,计算月薪,/,虚函数,输出编号、姓名,2026/11/11,20,/Manager.h,#,ifndef,MANAGER_H,#define MANAGER_H,class Manager:public Employee,public:,Manager(const long,const char*,double=0.0);,Manager(),void,setMonthlySalary(double,);,virtual double earnings()const;,virtual void print()const;,private:,double,monthlySalary,;,;,#,endif,Employee,HourWorker,Manager,PieceWorker,2026/11/11,21,/Manager.h,#,ifndef,MANAGER_H,#define MANAGER_H,class Manager:public Employee,public:,Manager(const long,const char*,double=0.0);,Manager(),void,setMonthlySalary(double,);,virtual double earnings()const;,virtual void print()const;,private:,double,monthlySalary,;,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,私有数据,月薪,2026/11/11,22,/Manager.h,#,ifndef,MANAGER_H,#define MANAGER_H,class Manager:public Employee,public:,Manager(const long,const char*,double=0.0);,Manager(),void,setMonthlySalary(double,);,virtual double earnings()const;,virtual void print()const;,private:,double,monthlySalary,;,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,置月薪,/,私有数据,月薪,2026/11/11,23,/Manager.h,#,ifndef,MANAGER_H,#define MANAGER_H,class Manager:public Employee,public:,Manager(const long,const char*,double=0.0);,Manager(),void,setMonthlySalary(double,);,virtual,double earnings()const;,virtual void print()const;,private:,double,monthlySalary,;,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,置月薪,/,计算管理人员月薪,/,私有数据,月薪,2026/11/11,24,/Manager.h,#,ifndef,MANAGER_H,#define MANAGER_H,class Manager:public Employee,public:,Manager(const long,const char*,double=0.0);,Manager(),void,setMonthlySalary(double,);,virtual double earnings()const;,virtual,void print()const;,private:,double,monthlySalary,;,;,#,endif,Employee,HourWorker,Manager,PieceWorker,/,置月薪,/,计算管理人员月薪,/,输出管理人员信息,/,私有数据,月薪,2026/11/11,25,Employee,HourWorker,Manager,PieceWorker,/,HourlyWorker.h,#,ifndef,HOURLYWORKER_H,#define HOURLYWORKER_H,class,HourlyWorker,:public Employee,public:,HourlyWorker(const,long,const char*,double=0.0,int,=0);,HourlyWorker,(),void,setWage(double,);,void,setHours(int,);,virtual double earnings()const;,virtual void print()const;,private:,double wage;,double hours;,;,#,endif,2026/11/11,26,Employee,HourWorker,Manager,PieceWorker,/,HourlyWorker.h,#,ifndef,HOURLYWORKER_H,#define HOURLYWORKER_H,class,HourlyWorker,:public Employee,public:,HourlyWorker(const,long,const char*,double=0.0,int,=0);,HourlyWorker,(),void,setWage(double,);,void,setHours(int,);,virtual double earnings()const;,virtual void print()const;,private:,double wage;,double hours;,;,#,endif,/,时薪,/,工时,2026/11/11,27,Employee,HourWorker,Manager,PieceWorker,/,HourlyWorker.h,#,ifndef,HOURLYWORKER_H,#define HOURLYWORKER_H,class,HourlyWorker,:public Employee,public:,HourlyWorker(const,long,const char*,double=0.0,int,=0);,HourlyWorker,(),void,setWage(double,);,void,setHours(int,);,virtual double earnings()const;,virtual void print()const;,private:,double wage;,double hours;,;,#,endif,/,时薪,/,工时,/,置时薪,/,置工时,2026/11/11,28,Employee,HourWorker,Manager,PieceWorker,/,HourlyWorker.h,#,ifndef,HOURLYWORKER_H,#define HOURLYWORKER_H,class,HourlyWorker,:public Employee,public:,HourlyWorker(const,long,const char*,double=0.0,int,=0);,HourlyWorker,(),void,setWage(double,);,void,setHours(int,);,virtual,double earnings()const;,virtual,void print()const;,private:,double wage;,double hours;,;,#,endif,/,置时薪,/,置工时,/,输出计时工月薪,/,计算计时工月薪,/,时薪,/,工时,2026/11/11,29,Employee,HourWorker,Manager,PieceWorker,/,PieceWorker.h,#,ifndef,PIECEWORKER_H,#define PIECEWORKER_H,class,PieceWorker,:public Employee,public:,PieceWorker(const,long,const char*,double=0.0,int,=0);,PieceWorker,(),void,setWage,(double);,void,setQuantity,(,int,);,virtual double earnings()const;,virtual void print()const;,private:,double,wagePerPiece,;,int,quantity;,;,#,endif,2026/11/11,30,Employee,HourWorker,Manager,PieceWorker,/,PieceWorker.h,#,ifndef,PIECEWORKER_H,#define PIECEWORKER_H,class,PieceWorker,:public Employee,public:,PieceWorker(const,long,const char*,double=0.0,int,=0);,PieceWorker,(),void,setWage,(double);,void,setQuantity,(,int,);,virtual double earnings()const;,virtual void print()const;,private:,double,wagePerPiece,;,int,quantity;,;,#,endif,/,每件工件薪金,/,工件数,2026/11/11,31,Employee,HourWorker,Manager,PieceWorker,/,PieceWorker.h,#,ifndef,PIECEWORKER_H,#define PIECEWORKER_H,class,PieceWorker,:public Employee,public:,PieceWorker(const,long,const char*,double=0.0,int,=0);,PieceWorker,(),void,setWage,(double);,void,setQuantity,(,int,);,virtual double earnings()const;,virtual void print()const;,private:,double,wagePerPiece,;,int,quantity;,;,#,endif,/,置每件工件薪金,/,置工件数,/,每件工件薪金,/,工件数,2026/11/11,32,Employee,HourWorker,Manager,PieceWorker,/,PieceWorker.h,#,ifndef,PIECEWORKER_H,#define PIECEWORKER_H,class,PieceWorker,:public Employee,public:,PieceWorker(const,long,const char*,double=0.0,int,=0);,PieceWorker,(),void,setWage,(double);,void,setQuantity,(,int,);,virtual,double earnings()const;,virtual,void print()const;,private:,double,wagePerPiece,;,int,quantity;,;,#,endif,/,置每件工件薪金,/,置工件数,/,每件工件薪金,/,工件数,/,输出计件薪金,/,计算计件薪金,2026/11/11,33,Employee,HourWorker,Manager,PieceWorker,void test1(),cout,setiosflags(ios:fixed|ios:showpoint,)print();,basePtr,=,basePtr,-print();,basePtr,=,basePtr,-print();,basePtr,=,basePtr,-print();,basePtr,=,basePtr,-print();,basePtr,=,basePtr,-print();,2026/11/11,34,小结,虚函数和多态性使软件设计易于扩充。,派生类重载接口相同的虚函虚特性不变。,如果代码关联在编译时确定,称为静态联编。,基类指针可以指向派生类对象;以及基类中拥有虚函数,是支持多态性的前提。代码在运行时的晚期匹配称为动态联编。,如果一个基类中包含虚函数,通常把它的析构函数声明为虚析构函数。,纯虚函数由派生类定义实现版本。,具有纯虚函数的类称为抽象类。抽象类只能作为基类,不能建立实例化对象。抽象类指针使得派生的具体类对象具有多态操作能力。,2026/11/11,35,作业:,9.1,选择题,P352-6.7.,*上机通过 例,9-12.,2026/11/11,36,
展开阅读全文