【教学课件】第六章类和对象.ppt

上传人:wuy****n92 文档编号:79011458 上传时间:2023-03-19 格式:PPT 页数:53 大小:221KB
返回 下载 相关 举报
【教学课件】第六章类和对象.ppt_第1页
第1页 / 共53页
【教学课件】第六章类和对象.ppt_第2页
第2页 / 共53页
点击查看更多>>
资源描述

《【教学课件】第六章类和对象.ppt》由会员分享,可在线阅读,更多相关《【教学课件】第六章类和对象.ppt(53页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第六章第六章 类和对象类和对象6 6.1 面向对象程序设计概述面向对象程序设计概述 6 6.2 结构结构 6.3 类和对象类和对象 6.4 继承和派生继承和派生 6.5多态性多态性 6.6 程序举例程序举例6.1 6.1 面向对象程序设计(面向对象程序设计(OOPOOP)概述)概述基本概念基本概念 Object Oriented Programming 对象:现实世界的实体,每个对象都有所属的类对象:现实世界的实体,每个对象都有所属的类 类:类:对一组对象共同具有的属性和行为的抽象,对一组对象共同具有的属性和行为的抽象,具有封装和隐藏性、还具有继承性。具有封装和隐藏性、还具有继承性。消息:向某

2、对象请求服务的一种表达方式,是对消息:向某对象请求服务的一种表达方式,是对 象与外界、对象与其它对象之间联系的工具象与外界、对象与其它对象之间联系的工具 方法:对某对象接受消息后所采取的操作的描述。方法:对某对象接受消息后所采取的操作的描述。特点特点封装性封装性继承性继承性多态性多态性C+C+中,通过类和对象实现对数据的封装,使得程序的修改维护中,通过类和对象实现对数据的封装,使得程序的修改维护更方便。是更方便。是OOPOOP的基础的基础。连接类与类的层次模型,利用现有类派生出新类的过程称为类连接类与类的层次模型,利用现有类派生出新类的过程称为类继承继承,支持代码重用、提供了无限重复利用程序资

3、源的途径、支持代码重用、提供了无限重复利用程序资源的途径、节省程序开发的时间和资源,是节省程序开发的时间和资源,是OOPOOP的关键。的关键。发出同样的消息被不同类型的对象接收时导致完全不同的行发出同样的消息被不同类型的对象接收时导致完全不同的行为为,是是OOPOOP的重要补充的重要补充说明结说明结构类型构类型的关键字的关键字 6.2 6.2 结构结构C+C+中的类从中的类从C C语言中的结构概念演变而来语言中的结构概念演变而来 结构类型说明形式结构类型说明形式struct 结构类型标识符结构类型标识符 结构成员结构成员1;1;结构成员结构成员2;2;结构成员结构成员n;n;类型可任意类型可任

4、意(不能为该结构自身)(不能为该结构自身)struct date int month;int day;int year;struct man char name15;char sex;int age;date birthday;如,说明一个结构类型如,说明一个结构类型datedate,含三个整型数据成员,含三个整型数据成员在此基础上,又在此基础上,又可说明另一个结可说明另一个结构类型构类型manmanbirthdayNamesexagemonthdayyearstructman结构类型结构变量定义结构变量定义先说明结构类型再定义结构变量先说明结构类型再定义结构变量在说明结构数据类型的同时定义结

5、构变量在说明结构数据类型的同时定义结构变量省略结构标识符直接定义结构类型变量省略结构标识符直接定义结构类型变量struct man man1,man2;struct man char name15;char sex;int age;struct date birthday;man1,man2;struct char name15;char sex;int age;struct date birthday;man1,man2;无类型名变量无类型名变量结构变量的引用结构变量的引用形式:形式:结构变量名结构变量名.成员名成员名(*(*指向结构的指针指向结构的指针).).成员名成员名 指向结构的指针指

6、向结构的指针-成员名成员名或或或或通过指向结构的指针引用结构变量成员通过指向结构的指针引用结构变量成员成员访问运算符成员访问运算符优先级最高的优先级最高的四个运算符之一四个运算符之一 括号不能少括号不能少如,假设有定义如,假设有定义manm,*p=&m;strcpy(m.name,Fang Min);p-birthday.month=8;则可如下引用结构成员则可如下引用结构成员6.3 6.3 类和对象类和对象#include iostream.hclass Circleprivate:double x,y,r;public:void print()cout圆心圆心:(x,y)endl;cout

7、半径半径:rendl;void set(double x1,double y1,double r1)x=x1;y=y1;r=r1;void main()Circle p;p.set(0,0,2);p.print();引例引例类定义类定义数据成员数据成员成员函数成员函数定义类对象定义类对象对对象调用对对象调用成员函数成员函数CircleCircle类将圆的属性类将圆的属性(圆心坐标和半径)(圆心坐标和半径)和操作(和操作(printprint、setset)封装在一起)封装在一起 上述定义的上述定义的CircleCircle类实际上也相当于一种新的数据类实际上也相当于一种新的数据类型,包含了数据

8、和对数据的操作,其成员描述如下:类型,包含了数据和对数据的操作,其成员描述如下:数据成员数据成员成员函数成员函数名称名称含义含义名称名称功能功能x圆心坐标圆心坐标x值值set设置数据成员值设置数据成员值y圆心坐标圆心坐标 y值值print输出数据成员值输出数据成员值r圆半径圆半径6.3.1 6.3.1 类的定义类的定义类是一种复杂的数据类型,它是将不同类型的类是一种复杂的数据类型,它是将不同类型的数据和与这些数据相关的运算封装在一起的集合体,数据和与这些数据相关的运算封装在一起的集合体,类的结构是用来确定一类对象的行为,而这些行为是类的结构是用来确定一类对象的行为,而这些行为是通过类的内部数据

9、结构和相关的操作来确定的。通过类的内部数据结构和相关的操作来确定的。定义格式:定义格式:class 类名类名public:;private:;protected:;;类的说明类的说明类的说明类的说明类的说明类的说明类的说明类的说明实现部分实现部分定义类的关键定义类的关键字字说明说明部分部分实现部分实现部分访访问问权权限限修修饰饰符符说明:说明:定义包括说明部分和实现部分。若成员函数在说明部分定义包括说明部分和实现部分。若成员函数在说明部分已定义,则实现部分可省略。已定义,则实现部分可省略。访问权限修饰符:访问权限修饰符:public(公有)、公有)、private(私有私有)和)和 prote

10、cted(保护)保护)缺省时为缺省时为private。公有成员通常为成员函数,可在程序中引用,私有成员公有成员通常为成员函数,可在程序中引用,私有成员通常是数据成员,只有成员函数或友元函数才可引用。通常是数据成员,只有成员函数或友元函数才可引用。类体中不允许对数据成员初始化。类体中不允许对数据成员初始化。自身类的对象不可以作为自己的成员自身类的对象不可以作为自己的成员class Bprivate:int year=2002,month=10,day=12;B b;错错数据成员数据成员成员函数成员函数名称名称含义含义名称名称功能功能name职员姓名职员姓名set设置数据成员值设置数据成员值sex

11、职员性别职员性别display 输出数据成员值输出数据成员值wage 职员工资职员工资 如,定义一个职工类,该类是对所有职工某些信如,定义一个职工类,该类是对所有职工某些信息的抽象,包括如下成员:息的抽象,包括如下成员:class Staffprivate:char name30;char sex;float wage;public:void display();void set(char*n,char s,float w);;void Staff:display()coutname:sex,wageendl;void Staff:set(char*n,char s,float w)strcp

12、y(name,n);sex=s;wage=w;说明部分说明部分实现部分实现部分作用域运算作用域运算符(类体外符(类体外实现时需要)实现时需要)6.3.2 6.3.2 对象的定义对象的定义类名仅提供一种类型定义,只有在定义属于类的变类名仅提供一种类型定义,只有在定义属于类的变量后,系统才会为其预留空间,这种变量称为对象,它量后,系统才会为其预留空间,这种变量称为对象,它是类的实例。是类的实例。格式格式:如,假设如,假设A A是一个已定义过的类,则可定义:是一个已定义过的类,则可定义:指向指向A类对象的指针类对象的指针A类的对象类的对象对象数组对象数组类名类名 对象名表;对象名表;A a1,*p,

13、a5成员引用成员引用一般对象成员一般对象成员数据成员:数据成员:成员函数:成员函数:()指向对象的指针的成员表示法:指向对象的指针的成员表示法:数据成员:数据成员:成员函数:成员函数:对象名对象名 成员名成员名对象名成员名(参数表)对象名成员名(参数表)对象指针名对象指针名-成员名成员名(*(*对象指针名对象指针名).).成员名成员名或或 对象指针名对象指针名-成员名成员名(参数表参数表)(*对象指针名对象指针名.成员名(参数表)成员名(参数表)引用方式同结构成员引用方式同结构成员#include iostream.h#include string.hclass Staffprivate:ch

14、ar name30;char sex;float wage;public:void display()coutname:sex,wageset(GaoLing,f,2003);s1-display();S1为指向为指向s的指针的指针可修改为如下形式吗可修改为如下形式吗?s.name=“WangQiang”s.sex=m;s.wage=1526例例6-16.3.3 6.3.3 对象的初始化对象的初始化1.1.构造函数和析构函数构造函数和析构函数 例例6-2 6-2 看引例的另一种实现看引例的另一种实现#include iostream.hclass Circleprivate:double x,

15、y,r;public:void print()cout圆心圆心:(x,y)endl;cout半径半径:rendl;Circle(double x1,double y1,double r1)x=x1;y=y1;r=r1;void main()Circle p(0,0,2);p.print();构造函数、构造函数、同类名同类名1.定义的同时初定义的同时初始化对象始化对象2.省略对赋初值省略对赋初值成员函数的额外成员函数的额外调用调用构造函数特点构造函数特点析构函数特点:析构函数特点:若一个对象被定义在函数体内,则当该函数结束时,若一个对象被定义在函数体内,则当该函数结束时,该对象的析构函数被自动调

16、用。该对象的析构函数被自动调用。当一个对象是使用当一个对象是使用newnew运算符被动态创建的,在使用运算符被动态创建的,在使用deletedelete释放时,析构函数将会被自动调用释放时,析构函数将会被自动调用是成员函数,可写在类体内,亦可写在类体外。是成员函数,可写在类体内,亦可写在类体外。函数名同类名,不能指定函数类型,可以带参数。函数名同类名,不能指定函数类型,可以带参数。可重载,即可定义多个参数个数不同的函数。可重载,即可定义多个参数个数不同的函数。在创建对象时由系统自动调用,程序中不能直接调用在创建对象时由系统自动调用,程序中不能直接调用。是成员函数,可写在类体内,亦可写在类体外。

17、是成员函数,可写在类体内,亦可写在类体外。函数名同类名,前面多个字符函数名同类名,前面多个字符“”,不指定类型,无参。,不指定类型,无参。不可重载,即一个类只能定义一个析构函数。不可重载,即一个类只能定义一个析构函数。可被调用,也可由系统调用。系统自动调用情况如下:可被调用,也可由系统调用。系统自动调用情况如下:2.2.缺省构造函数和缺省析构函数缺省构造函数和缺省析构函数形式:形式:说明:说明:若若没有定义任何构造函数没有定义任何构造函数,系统会自动生成上述无参的缺省,系统会自动生成上述无参的缺省构造函数及析构函数构造函数及析构函数若定义一个若定义一个静态静态对象而没有指明初始化时,编译器会按

18、缺省对象而没有指明初始化时,编译器会按缺省构造函数对对象的所有数据成员都初始化为或空。构造函数对对象的所有数据成员都初始化为或空。:():()例例6.3 6.3 定义一个定义一个Circle1Circle1类,具有求一个圆的面积、类,具有求一个圆的面积、求两个圆的面积之和,以及输出面积等功能求两个圆的面积之和,以及输出面积等功能 。#include iostream.hclass Circle1private:double x,y,r,s;public:void print()cout圆心圆心:(x,y)endl;cout半径半径:rendl;Circle1()Circle1(double x

19、1,double y1,double r1)x=x1;y=y1;r=r1;void addarea(Circle1 p1,Circle1 p2)s=3.14*(p1.r*p1.r)+3.14*(p2.r*p2.r);void disp()cout面积面积:sendl;void main()Circle1 p1(0,0,2),p2(1,1,4),p3;p1.print();p2.print();p3.addarea(p1,p2);p3.disp();可缺省吗?验证一下可缺省吗?验证一下初始化了吗初始化了吗#include#include class countint num;public:cou

20、nt();count();void process();count:count()num=0;count:count()cout字符个数:字符个数:numendl;void count:process()while(cin.get()!=n)num+;coutendl;void main()count c;cout输入一个句子:输入一个句子:;c.process();例例6.4 6.4 析构函数示例析构函数示例析构函数中输出处理结析构函数中输出处理结果果(未设专门输出函数)未设专门输出函数)析构函数在程序结束析构函数在程序结束前由系统自动调用前由系统自动调用3.3.拷贝初始化构造函数拷贝初始化

21、构造函数 例例6.56.5#include iostream.hclass Circle1private:double x,y,r,s;public:void print()cout圆心圆心:(x,y)endl;cout半径半径:rendl;Circle1(double x1,double y1,double r1)x=x1;y=y1;r=r1;Circle1(Circle1&p)x=p.x;y=p.y,r=p.r;void main()Circle1 p1(0,0,2),p2(p1);p1.print();p2.print();用于用已知对象初始化被创建的同类对象用于用已知对象初始化被创建的

22、同类对象只有一个参数,且是对某个对象的引用只有一个参数,且是对某个对象的引用常用于做函数的形参及返回值常用于做函数的形参及返回值拷贝初始化构造函拷贝初始化构造函数数(引用做参数引用做参数)已知对象做已知对象做初值初值常对象和常成员常对象和常成员 1.1.常成员函数常成员函数形式:形式:类型说明符类型说明符 函数名函数名(参数表参数表)const)const不修改对象数据成员的成员函数才能声明为不修改对象数据成员的成员函数才能声明为constconst函数函数构造函数和析构函数不能声明为构造函数和析构函数不能声明为constconst只有常成员函数可以操作常对象只有常成员函数可以操作常对象说明:

23、说明:例例6.66.6常成员函数示例常成员函数示例#include iostream.hclass Timeprivate:int hour,minute,second;public:Time:Time()Time:Time(int h,int m,int s)hour=h;minute=m;second=s;void settime(int h,int m,int s)hour=h;minute=m;second=s;void print()const couthour:minute:secondendl;void main()Time t1;const Time t2(10,23,34);

24、/定义定义t2为常对象为常对象 t1.settime(11,15,20);t1.print();/t2.settime(4,12,15);t2.print();前面的解释符可去掉吗前面的解释符可去掉吗不修改数据成员,不修改数据成员,定义为常函数定义为常函数settime函数可函数可声明为声明为const吗吗2.2.常数据成员常数据成员 对不应该被修改的数据成员声明为对不应该被修改的数据成员声明为constconst,可使其受,可使其受到强制保护,初始化方式与一般数据成员不同。到强制保护,初始化方式与一般数据成员不同。class Decrement private:int num;const i

25、nt dec;/将将dec声明为常数据成员声明为常数据成员 public:Decrement(int n,int d):dec(d)num=n;void fdec()num=num-dec;void print()const coutnum=num,dec=decendl;初始化列表的初始化列表的方式初始化方式初始化静态成员静态成员静态成员的提出是为了解决静态成员的提出是为了解决数据共享数据共享的问题,它比全局变的问题,它比全局变量在实现数据共享时更为安全,是实现同类多个对象数据共享量在实现数据共享时更为安全,是实现同类多个对象数据共享的好方法。在类中,分为静态数据成员和静态函数。的好方法。在

26、类中,分为静态数据成员和静态函数。1 1。静态数据成员。静态数据成员初始化格式:初始化格式:数据类型数据类型 类名类名:静态数据成员静态数据成员=值值是类的成员,被所有对象所共享,在内存中只存贮一次是类的成员,被所有对象所共享,在内存中只存贮一次定义或说明时前面加关键字定义或说明时前面加关键字staticstatic初始化在类外进行,不加初始化在类外进行,不加staticstatic和访问权限修饰符和访问权限修饰符 例例6.7 6.7 静态数据成员示例程序静态数据成员示例程序 通过以下程序了解静态数据成员的声明、初始化的位置通过以下程序了解静态数据成员的声明、初始化的位置和限定及具有类对象共享

27、的属性。和限定及具有类对象共享的属性。#include class Tcprivate:int i;static int k;public:Tc()i=0;i+;k+;void display()couti,1创建创建B时时k值值1-2。1,21,22.2.静态成员函数静态成员函数调用形式调用形式:静态成员函数中数据成员的引用也有区别静态成员函数中数据成员的引用也有区别:例例6.8静态成员函数应用程序示例静态成员函数应用程序示例静态成员函数是类的成员函数静态成员函数是类的成员函数,而非对象的成员。而非对象的成员。类名类名:静态成员函数名静态成员函数名(参数表参数表)对静态数据成员,直接引用对静

28、态数据成员,直接引用对非静态数据成员,通过对象引用对非静态数据成员,通过对象引用#include class Tcprivate:int A;static int B;public:Tc(int a)A=a;B+=a;static void display(Tc C)coutC.AB;;int Tc:B=2;void main()Tc A(2),B(4);Tc:display(A);Tc:display(B);静态成静态成员函数员函数的调用的调用非静态数非静态数据成员的据成员的引用引用静态数据静态数据成员的引成员的引用用 通过该程序了解通过该程序了解程序程序中静态成员函数的调用方式以及中静态成

29、员函数的调用方式以及静态成静态成员函数员函数中静态数据成员和非静态数据成员的引用方式中静态数据成员和非静态数据成员的引用方式6.3.6 6.3.6 友元函数友元函数 例例6.96.9友元函数示例程序友元函数示例程序#include#include class Cpointprivate:int X,Y;public:Cpoint(int x,int y)X=x;Y=y;void print();friend double dist(Cpoint&a,Cpoint&b);void Cpoint:print()coutXY;double dist(Cpoint&a,Cpoint&b)int dx=

30、a.X-b.X;int dy=a.Y-b.Y;return sqrt(dx*dx+dy*dy);void main()Cpoint p1(3,4),p2(6,8);p1.print();p2.print();double d=dist(p1,p2);/*友元不是成友元不是成员函数不需对象表示,直接调用员函数不需对象表示,直接调用*/coutDistance is dendl;友元函数说明友元函数说明前不能加前不能加 friend为非成员函数为非成员函数可访问类中私有成员可访问类中私有成员说明时前面加关键字说明时前面加关键字friendfriend标识标识计算机系人员计算机系人员学生学生研究生研

31、究生本科生本科生系主任系主任行政管理人员行政管理人员教务教务教师教师教职工教职工6.4 6.4 继承和派生继承和派生基类基类(父类)(父类)派生类派生类(子类)(子类)多继承多继承单继承单继承class Cylinder1:public Circleprivate:double h;public:void print()Circle:print();cout圆柱高圆柱高:hendl;void set(double x1,double y1,double r1,double h1)Circle:set(x1,y1,r1);h=h1;class Cylinderprivate:double x,y

32、,r,h;public:void print()cout圆心圆心:(x,y)endl;cout半径半径:r ,圆柱高圆柱高:hendl;void set(double x1,double y1,double r1,double h1)x=x1;y=y1;r=r1;h=h1;对比如下两个圆柱体类的定义对比如下两个圆柱体类的定义全部数据成全部数据成员重新定义员重新定义只定义一个新成只定义一个新成员员(Circle中没有)中没有)通过调用通过调用Circle类成员类成员函数输出函数输出Circle类成员类成员从从Circle类类中派生而来中派生而来单继承单继承 1.1.派生类的定义格式派生类的定义格

33、式原有类(父类)原有类(父类)class 派生类名派生类名:继承方式继承方式 基类名基类名 派生类新定义成员;派生类新定义成员;public(公有基类公有基类)private(私有基类私有基类)protected(保护基类保护基类)若若要要在在派派生生类类Cylinder1Cylinder1中中再再增增加加一一个个成成员员函函数数volumevolume,用用以以求求圆圆柱柱体体的的体体积积,则则该该成成员员函函数数能能否否如如下实现:下实现:double Cylinder1:volume()return(3.14*r*r*h);错!错!r r是是CircleCircle类的私有成员,类的私有

34、成员,不能被派生类访问不能被派生类访问2.2.继承方式继承方式public,private和和protected 是三种常用的继承方式,继承方式的不是三种常用的继承方式,继承方式的不同决定了派生类对基类成员的访问权限不同。同决定了派生类对基类成员的访问权限不同。基基类私有成私有成员(privateprivate)公有成公有成员(publicpublic)保保护成成员(protected)(protected)私有派生私有派生类(privateprivate)不可不可访问的成的成员私有成私有成员私有成私有成员公有派生公有派生类(publicpublic)不可不可访问的成的成员公有成公有成员保保护

35、成成员保保护派生派生类(protected)(protected)不可不可访问的成的成员保保护成成员保保护成成员派生类的继承关系派生类的继承关系 例例6.106.10分析下列程序中的访问权限,并回答所提的问题。分析下列程序中的访问权限,并回答所提的问题。#include class Apublic:void f1();A()i1=10;j1=11;protected:int j1;private:int i1;class B:public Apublic:void f2();B()i2=20;j2=21;protected:int j2;private:int i2;class C:publi

36、c Bpublic:void f3();C()i3=30;j3=31;protected:int j3;private:int i3;void main()A a;B b;C c;(1)f2()能否访问能否访问f1(),i1,j1?能访问能访问f1()、j1,不能访问不能访问i1(2)能否访问能否访问f(),i1,j1?能访问能访问f1(),不能访问不能访问i1和和j1(3)f3()能能否否访访问问f2()、i2和和j2,以及,以及f1(),j1和和i1?f3能能访访问问f2()和和j2,以以及及f1()和和j1,但不能访问,但不能访问i1和和i2(4)c能否访问能否访问f2(),i2和和j2

37、?以及?以及f1(),j1和和i1?能访问能访问f2()和和f1(),其它的都,其它的都不能访问不能访问#include iostream.hclass Circleprivate:double x,y,r;public:void print()cout圆心圆心:(x,y);coutendl半径半径:rendl;void set(double x1,double y1,double r1)x=x1;y=y1;r=r1;double getr()return r;class Cylinder1:public Circleprivate:double h;public:void print()Ci

38、rcle:print();cout圆柱高圆柱高:hendl;void set(double x1,double y1,double r1,double h1)Circle:set(x1,y1,r1);h=h1;double volume()double R=getr();return(3.14*R*R*h);void main()Cylinder1 p;p.set(0,0,2,3);p.print();coutvolume=p.volume();该函数返回值为圆半径,为派该函数返回值为圆半径,为派生类能使用半径提供一个接口生类能使用半径提供一个接口 派生类可访问派生类可访问基类公有成员基类公有

39、成员 例例6.116.11派生类示例程序派生类示例程序3.3.构造函数和析构函数构造函数和析构函数 派派生生类类的的构构造造函函数数除除了了对对自自己己的的数数据据成成员员初初始始化化外外,还还负负责责调调用用基基类类构构造造函函数数使使基基类类的的数数据据成成员员得得以以初初始始化化,当当对对象象被被删删除除时时,派派生生类的析构函数被执行,同时基类的析构函数也将被调用。类的析构函数被执行,同时基类的析构函数也将被调用。格式:格式:派生类名派生类名(派生类构造函数总参数表派生类构造函数总参数表):):基类构造函数基类构造函数(参数表参数表1)1);基类中有缺省的构造函数或没定义构造函数,则派

40、生类构造函数的基类中有缺省的构造函数或没定义构造函数,则派生类构造函数的定义中可省略对基类构造函数的调用,而隐式调用缺省构造函数。定义中可省略对基类构造函数的调用,而隐式调用缺省构造函数。基类构造函数中,只有有参的构造函数,则派生类构造函数中必须基类构造函数中,只有有参的构造函数,则派生类构造函数中必须 调用基类构造函数,提供将参数传递给基类构造函数的途径调用基类构造函数,提供将参数传递给基类构造函数的途径派生类构造函数的调用顺序为先基类,后派生类。派生类构造函数的调用顺序为先基类,后派生类。派生类析构函数的执行顺序为先派生类,后基类。派生类析构函数的执行顺序为先派生类,后基类。说明:说明:#

41、includeiostream.h#include string.hclass Staffprivate:char name30;char sex;float wage;public:void display()coutname:sex,ageendl;Staff(char*n,char s,float w)strcpy(name,n);sex=s;wage=w;class Staff1:public Staffprivate:int wt;public:Staff1(char*n,char s,float w,int t):Staff(n,s,w)wt=t;double addwage()r

42、eturn(wt/10*80);void display()Staff:display();coutwt,addwage()endl;void main()Staff1s(WangQiang,m,1526,21);s.display();例例6.126.12派生类构造函数示例程序派生类构造函数示例程序派生类构造函数中派生类构造函数中调用基类构造函数调用基类构造函数 6.56.5多态性多态性 发出同样的消息被不同类型的对象接收时导致完发出同样的消息被不同类型的对象接收时导致完全不同的行为。全不同的行为。函数重载(已介绍过)函数重载(已介绍过)运算符重载运算符重载基于虚函数的多态性基于虚函数的多态

43、性6.5.1 6.5.1 运算符重载运算符重载 赋予已有的运算符多重含义,通过重新定义运赋予已有的运算符多重含义,通过重新定义运算符使它能够用于特定类的对象以完成特定的功能。算符使它能够用于特定类的对象以完成特定的功能。例例6.136.13重载重载“+”“+”运算运算 ,用以实现两个字符串的连,用以实现两个字符串的连接接#include iostream.h#include string.h#include stdio.hclass Strprivate:char*s;int len;public:Str()Str(char*s1)len=strlen(s1);s=new charlen;st

44、rcpy(s,s1);void print()coutsendl;Str operator+(Str s1)return(strcat(s,s1.s);void main()char str1100,str2100;gets(str1);gets(str2);Str s1(str1),s2(str2),s3;s3=s1+s2;s3.print();对加法运算对加法运算符进行重载符进行重载 s3=s1.operator+(s2s3=s1.operator+(s2)重载形式:重载形式:重载为类的成员函数:重载为类的成员函数:类名类名 operator 运算符运算符(参数表参数表)程序中表达形式:程

45、序中表达形式:c1 c1 运算符运算符 c2 c2编译程序解释形式:编译程序解释形式:c1 operator c1 operator 运算符运算符(c2)(c2)重载为类的友元函数:重载为类的友元函数:friend类名类名operator运算符运算符(参数表参数表)程序中表达形式:程序中表达形式:c1 c1 运算符运算符 c2 c2编译程序解释形式:编译程序解释形式:operator operator 运算符运算符(c1,c2)(c1,c2)将例将例6.13中的加法运算符重载为友元函数的形式如下:中的加法运算符重载为友元函数的形式如下:friend Str operator+(Str s1,S

46、tr s2)return(strcat(s1.s,s2.s);隐含了指向隐含了指向c1的的this指针指针this 指针指针 无需定义而隐含于每个类的成员函数中无需定义而隐含于每个类的成员函数中指向正在被某个成员函数操作的对象指向正在被某个成员函数操作的对象可以用可以用*thisthis来标识调用该成员函数的对象来标识调用该成员函数的对象通常情况下,程序中并不显式地使用通常情况下,程序中并不显式地使用thisthis指针指针 例例6.146.14自增运算符重载(自增运算符重载(this 指针使用示例)指针使用示例)#include iostream.hclass Aprivate:int x;

47、public:A(int x1)x=x1;void print()coutxendl;A operator+()x+;return(*this);void main()A a(5);(+a).print();返回调用成员函返回调用成员函数的对象自身数的对象自身 自增重载运算作自增重载运算作用于用于A A类对象类对象a a等价于如下两条语句:等价于如下两条语句:+a;a.print();虚函数虚函数虚函数说明方式虚函数说明方式 虚函数是动态联编的基础,它是一种非虚函数是动态联编的基础,它是一种非staticstatic的成员函数的成员函数实现动态联编的条件实现动态联编的条件virtual 类型说

48、明符类型说明符 函数名函数名 (参数表参数表)基基类中有说明的类中有说明的虚函数虚函数调用虚函数操作的只能是对象指针或对象引用,调用虚函数操作的只能是对象指针或对象引用,否则仍为静态联编否则仍为静态联编 例例6.156.15虚函数示例程序虚函数示例程序#include iostream.hclass Animalpublic:void character()cout动物特征动物特征:不同不同.n;virtual food()cout动物食物动物食物:不同不同.n;class Giraffe:public Animalpublic:void character()cout长颈鹿特征长颈鹿特征:长

49、颈长颈.n;virtual food()cout长颈鹿食物长颈鹿食物:树叶树叶.n;class Elephant:public Animalpublic:void character()cout大象特征大象特征:长鼻子长鼻子.n;virtual food()coutcharacter();p-food();void main()Giraffe g;f(&g);/实参为派生类对象的地址实参为派生类对象的地址 Elephant e;f(&e);/实参为派生类对象的地址实参为派生类对象的地址观察运行结果观察运行结果void f(Animal&p)/形参为基类形参为基类对象的引用对象的引用p.char

50、acter();p.food();void main()Giraffe g;f(g);/实参为派生类对象实参为派生类对象 Elephant e;f(e);/实参为派生类对象实参为派生类对象void f(Animal p)/形参为基类形参为基类对象对象p.character();p.food();void main()Giraffe g;f(g);/实参为派生类对象实参为派生类对象 Elephant e;f(e);/实参为派生类对象实参为派生类对象若将程序的相应部分修改为如下两种形式,再观察运行结果若将程序的相应部分修改为如下两种形式,再观察运行结果从上述程序中可见:从上述程序中可见:只只有有当

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

当前位置:首页 > 教育专区 > 大学资料

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

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