面向对象程序设计(C++语言)三课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《面向对象程序设计(C++语言)三课件.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 对象 程序设计 C+ 语言 课件
- 资源描述:
-
1、李爱华 程磊 编著清华大学出版社同名教材配套电子教案20102010年年 2 2月月面向对象程序设计(面向对象程序设计(C+语言)语言)32第二部分第二部分 面向对象的程序设计面向对象的程序设计 第第3章类和对象章类和对象(一一)第第4章类和对象章类和对象(二二)第第5章继承和派生章继承和派生第第6章虚函数与多态性章虚函数与多态性第第7章运算符重载章运算符重载第第8章模板章模板第第9章标准模板库章标准模板库STL第第10章章 C+语言的输入和输出语言的输入和输出3第第5章继承和派生章继承和派生本章重点:本章重点:v继承与派生的概念;继承与派生的概念;v派生类的构造函数和析构函数的执行顺序与规派
2、生类的构造函数和析构函数的执行顺序与规则;则;v多继承的声明与实现;多继承的声明与实现;v基类成员访问原则;基类成员访问原则;v赋值兼容性;赋值兼容性;v虚基类的概念虚基类的概念;45.1继承与派生的概念继承与派生的概念 v继承继承是面向对象程序设计中重要的特性。是面向对象程序设计中重要的特性。v继承主要是指在己有类的或称为继承主要是指在己有类的或称为基类基类的基础上的基础上创建新类的过程,这个新类就是创建新类的过程,这个新类就是派生类派生类。v派生类自动的包含了基类的成员,包括所有的派生类自动的包含了基类的成员,包括所有的数据和操作,而且它还可以增加自身新的成员数据和操作,而且它还可以增加自
3、身新的成员5在在C+中,一个派生类可以从一个基类派生,也可以从多个基类派生,从一个基中,一个派生类可以从一个基类派生,也可以从多个基类派生,从一个基类派生的称为单继承,如图类派生的称为单继承,如图5.1。图。图5.2中的树型结构图可以体现学生体系的中的树型结构图可以体现学生体系的概念。概念。图图5.1 5.1 单继承单继承 图图5.2 5.2 类的层次树型结构图类的层次树型结构图 6v一个派生类从两个或多个基类派生则称为多继承,如图一个派生类从两个或多个基类派生则称为多继承,如图5.3所示,它使一个所示,它使一个类可以融合了多个类的特征,例如在现实生活中的在职研究生的概念,他类可以融合了多个类
4、的特征,例如在现实生活中的在职研究生的概念,他是在职人员,又是研究生,如图是在职人员,又是研究生,如图5.4所示,从图中还可以看到一个有趣的现所示,从图中还可以看到一个有趣的现象,在职人员类本身是单继承的基类,教师和职员都是它的具体子类,而象,在职人员类本身是单继承的基类,教师和职员都是它的具体子类,而其又是在职研究生的多重基类,提供在职人员的基本特征。其又是在职研究生的多重基类,提供在职人员的基本特征。图图5.3 多继承多继承 图图5.4 单继承与多继承单继承与多继承 7继承机制除了支持软件复用外,还具备以下三个作继承机制除了支持软件复用外,还具备以下三个作用:用:v对事物进行分类。对事物进
5、行分类。v支持软件的增量开发。支持软件的增量开发。v对概念进行组合。对概念进行组合。8v前面的知识中,我们学习了如何定义类和如何实现类的抽象与封装,通常在不同的类中,数据前面的知识中,我们学习了如何定义类和如何实现类的抽象与封装,通常在不同的类中,数据成员和函数成员都是不同的,但对于某些特定的问题,有时候两个类的基本或大部分内容是相成员和函数成员都是不同的,但对于某些特定的问题,有时候两个类的基本或大部分内容是相同的,在图同的,在图5.2中给出了学生体系的概念,我们利用现有知识可以首先声明了一类中给出了学生体系的概念,我们利用现有知识可以首先声明了一类来描述学生这来描述学生这一基本概念一基本概
6、念,如下:,如下:class Student private:int number;char name20;public:Student()number=0;name0=0;Void SetValue(int n,char*s1)number=n;Strcpy(name,s1);void Print()cout”Number:”numberendl;cout”Name:”nameendl;;9v如果现在需要一个新类如果现在需要一个新类UGStudent来描述大学生概念,除上述的基本成员外,还需来描述大学生概念,除上述的基本成员外,还需要用到年龄、年级等信息,我们可以如下定义此类:要用到年龄、年
7、级等信息,我们可以如下定义此类:class UGStudent private:int number;char name20;int age;int grade;public:void Print()cout”Number:”numberendl;cout”Name:”nameendl;cout”Age:”ageendl;cout”Grade:”gradeendl;;105.2 派生类的声明派生类的声明 v在在C+中类的继承关系可以用如下语法表示:中类的继承关系可以用如下语法表示:class 派生类名派生类名:继承方式继承方式 基类名基类名 派生类成员声明派生类成员声明;v需要注意的是,基类的
8、构造函数和析构函数不需要注意的是,基类的构造函数和析构函数不能被派生类继承,派生类若要初始化基类的数能被派生类继承,派生类若要初始化基类的数据成员必须在构造函数中初始化。据成员必须在构造函数中初始化。11【例【例5.1】用继承重新定义】用继承重新定义UGStudent类。类。/*05_01.cpp*/class UGStudent:public Studentprivate:int age;int grade;public:UGStudent()SetValue(0,”);age=0;grade=0;UGStudent(int n,char*s1,int a,int g)SetValue(n,
9、s1);age=a;grade=g;void PrintExtra()cout”Age:”ageendl;cout”Grade:”gradeendl;12用主函数进行测试用主函数进行测试:int main()UGStudent st1(100,”wang”,18,1);st1.Print();/调用基类的函数调用基类的函数st1.PrintExtra();/调用派生类新定义的函数调用派生类新定义的函数return 0;13Number:100Name:wangAge:18Grade:1程序的运行结果为:程序的运行结果为:14图图5.5 基类与派生类中的成员基类与派生类中的成员 155.3 派生
10、类的访问属性派生类的访问属性 v类的成员可以分为类的成员可以分为public(公有)、公有)、protected(保护)和保护)和private(私有)三种访问权限。私有)三种访问权限。v类的非静态成员函数可以访问类中的所有成员,类的非静态成员函数可以访问类中的所有成员,但是通过类的但是通过类的“对象对象.成员成员”方式(在类的作用方式(在类的作用域之外),则只能访问该类的公有成员。域之外),则只能访问该类的公有成员。v类的继承方式有公有继承(类的继承方式有公有继承(public)、)、保护继保护继承(承(protected)和私有继承(和私有继承(private)三种。三种。v不同的继承方式
11、,导致原有基类成员在派生类不同的继承方式,导致原有基类成员在派生类中的访问属性也有所不同。中的访问属性也有所不同。16表表5.1不同继承方式下的访问控制权限不同继承方式下的访问控制权限基类成员的权限继承方式publicprotectedprivatepublic在派生类中为public在派生类中为protected在派生类中为private派生类的成员函数和类的作用域之外,都可以直接访问派生类的成员函数可以直接访问派生类的成员函数可以直接访问protected在派生类中为protected在派生类中为protected在派生类中为private派生类的成员函数可以直接访问派生类的成员函数可以直
12、接访问派生类的成员函数可以直接访问private在派生类中被隐藏,无法访问在派生类中被隐藏,无法访问在派生类中被隐藏,无法访问任何方式都不能直接访问,但可以通过基类的public、protected成员函数间接访问任何方式都不能直接访问,但可以通过基类的public、protected成员函数间接访问访问任何方式都不能直接访问,但可以通过基类的public、protected成员函数间接访问访问17v对于静态成员来说,与普通成员函数组合,将对于静态成员来说,与普通成员函数组合,将产生以下两种情况:产生以下两种情况:(1)派生类中静态函数对基类中静态成员的访问。派生类中静态函数对基类中静态成员的
13、访问。(2)派生类的普通成员函数要访问基类中的静态成员。派生类的普通成员函数要访问基类中的静态成员。v静态成员的访问控制变化完全遵循表静态成员的访问控制变化完全遵循表5.1的规则,的规则,这两种情况和派生类中普通成员函数访问基类这两种情况和派生类中普通成员函数访问基类中普通成员没有区别。中普通成员没有区别。18【例【例5.2】公有继承时的访问控制权限。】公有继承时的访问控制权限。/*05_02.cpp*/#includeusing namespace std;class Base private:int a;void fun1()coutaendl;protected:int b;void f
14、un2()coutcendl;public:int c;void fun3()coutbendl;void seta(int i)/修改私有成员修改私有成员a的值的值 a=i;int geta()/返回私有成员返回私有成员a的值的值 return a;Base(int i,int j,int k)/基类的构造函数基类的构造函数 a=i;b=j;c=k;19class Sub:public Base private:int d;public:Sub(int i,int j,int k,int m):Base(i,j,k)/派生类构造函数派生类构造函数 d=m;void test()/coutae
15、ndl;/错误,无法访问基类的私有成员错误,无法访问基类的私有成员coutb endl;/正确,可以访问基类的保护成员正确,可以访问基类的保护成员coutc endl;/正确,可以访问基类的公有成员正确,可以访问基类的公有成员/fun1();/错误,无法访问基类的私有成员错误,无法访问基类的私有成员fun2();/正确,可以访问基类的保护成员正确,可以访问基类的保护成员fun3();/正确,可以访问基类的公有成员正确,可以访问基类的公有成员seta(10);/正确,间接访问基类成员正确,间接访问基类成员acout d endl;/正确,可以访问派生类的私有成员正确,可以访问派生类的私有成员;2
16、0int main()Base b1(5,6,7);/cout b1.a;/错误,无法访问对象的私有成员错误,无法访问对象的私有成员/coutb1.b;/错误,错误,无法访问对象的保护成员无法访问对象的保护成员coutb1.cendl;/正确,可以访问对象的公有成员正确,可以访问对象的公有成员coutb1.geta()endl;/正确,间接访问对象的私有成员正确,间接访问对象的私有成员aSub s1(11,15,19,22);s1.test();/正确,可以访问对象的公有成员正确,可以访问对象的公有成员s1.c=200;/正确,可以访问对象的公有成员正确,可以访问对象的公有成员s1.fun3(
17、);/正确,可以访问对象的公有成员正确,可以访问对象的公有成员return 0;215.4 派生类的构造函数和析构函数派生类的构造函数和析构函数 v在继承机制中,基类的构造函数和析构函数是在继承机制中,基类的构造函数和析构函数是不能继承的。不能继承的。v派生类的构造函数负责对来自基类数据成员和派生类的构造函数负责对来自基类数据成员和新增加的数据成员进行初始化。新增加的数据成员进行初始化。v所以在执行派生类的构造函数时,需要调用基所以在执行派生类的构造函数时,需要调用基类的构造函数。类的构造函数。225.4.1 派生类构造函数和析构函数的执行顺序派生类构造函数和析构函数的执行顺序 v通过继承,派
18、生类得到了基类的成员,因此派生类对象通过继承,派生类得到了基类的成员,因此派生类对象中既包括自身类的数据成员还包括通过继承从基类中得中既包括自身类的数据成员还包括通过继承从基类中得到的数据成员。到的数据成员。v在派生类中还可用其他类来定义对象作为成员,又涉及在派生类中还可用其他类来定义对象作为成员,又涉及到派生类中对象成员的构造问题,则当用派生类定义对到派生类中对象成员的构造问题,则当用派生类定义对象后,派生类对象、对象成员、基类对象的构造函数的象后,派生类对象、对象成员、基类对象的构造函数的调用顺序如下:调用顺序如下:基类的构造函数。基类的构造函数。对象成员的构造函数(如果有的话),有多个时
19、按声明的顺序。对象成员的构造函数(如果有的话),有多个时按声明的顺序。派生类的构造函数。派生类的构造函数。23【例【例5.3】派生类构造实例。】派生类构造实例。/*05_03.cpp*/#includeusing namespace std;class Bpublic:B()cout”Construct B”endl;class Cpublic:C()cout”Construct C”endl;class D:public Bprivate:C c1;public:D()cout”Construct D”endl;int main()D d1;return 0;24construct BCon
20、struct CConstruct D程序的运行结果为:程序的运行结果为:25v析构函数与构造函数执行的顺相反,将按如下析构函数与构造函数执行的顺相反,将按如下顺序执行:顺序执行:(1)派生类的构造函数;派生类的构造函数;(2)对象成员的构造函数(如果有的话),有多个时对象成员的构造函数(如果有的话),有多个时与声明的顺序相反;与声明的顺序相反;(3)基类对象的析构函数。基类对象的析构函数。26对例对例5.3中的程序进行改造,为每一个类添加析构函数,然后再进行测试。中的程序进行改造,为每一个类添加析构函数,然后再进行测试。class Bpublic:B()cout”Construct B”en
21、dl;B()cout”Deconstruct B”endl;class Cpublic:C()cout”Construct C”endl;C()cout”Deconstruct C”endl;class D:public Bprivate:C c1;public:D()cout”Construct D”endl;D()cout”Deconstruct D”endl;int main()D d1;return 0;27Construct BConstruct CConstruct DDestruct DDestruct CDestruct B程序的运行结果为:程序的运行结果为:285.4.2 派
22、生类构造函数和析构函数的构造规则派生类构造函数和析构函数的构造规则 v在在C+中,类的机制非常清楚、严格地划分了中,类的机制非常清楚、严格地划分了各自的权限和责任。是哪个类的操作,必须由各自的权限和责任。是哪个类的操作,必须由那个类调用;那个类调用;v是谁的对象,就必须由该类的构造函数来完成是谁的对象,就必须由该类的构造函数来完成对其构造的工作。对其构造的工作。v因此,对派生类中基类成员的构造,必须由基因此,对派生类中基类成员的构造,必须由基类构造函数完成,而不能由派生类的构造函数类构造函数完成,而不能由派生类的构造函数越权去构造。越权去构造。v派生类构造函数主要负责调用基类构造函数并派生类构
23、造函数主要负责调用基类构造函数并提供基类构造函数所需的参数。提供基类构造函数所需的参数。29下面分两种情况讨论派生类对象的构造:下面分两种情况讨论派生类对象的构造:1如基类中定义了默认构造函数,且该默认构造函如基类中定义了默认构造函数,且该默认构造函数能够完成派生类对象中基类成员的构造,则派数能够完成派生类对象中基类成员的构造,则派生类构造函数无需显式调用基类构造函数,直接生类构造函数无需显式调用基类构造函数,直接调用基类的默认构造函数即可,这是一种较为简调用基类的默认构造函数即可,这是一种较为简单的情况,单的情况,例例5.3中的继承就属于此类情况,下面的例子也可中的继承就属于此类情况,下面的
24、例子也可以说明这一点。以说明这一点。30【例【例5.4】分析下面程序的输出结果。】分析下面程序的输出结果。/*05_04.cpp*/#includeusing namespace std;class Basepublic:Base()a=0;Base(int i)a=i;protected:int a;class Derived:public Basepublic:Derived()b=0;Derived(int i)b=i;void Print()couta=a,b=bendl;private:int b;31int main()Derived d1;Derived d2(12);d1.Pr
25、int();d2.Print();return 0;32a=0,b=0a=0,b=12程序的运行结果为:程序的运行结果为:332若基类中定义了有参数的构造函数,或者所定义的默认构若基类中定义了有参数的构造函数,或者所定义的默认构造函数不能完成基类成员的构造,则必须通过派生类构造造函数不能完成基类成员的构造,则必须通过派生类构造函数显式向调用基类的构造函数,向带参数的构造函数传函数显式向调用基类的构造函数,向带参数的构造函数传递参数,这需要用到递参数,这需要用到“成员初始化列表成员初始化列表”的语法。的语法。v 另外,对于派生类中普通数据成员的初始化,以及对象成另外,对于派生类中普通数据成员的初
展开阅读全文