版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、模块 10 派生类与继承高级语言程序设计基础(C&C+)2主要内容1 继承与派生的概念2 派生类的构成3 派生类的继承方式4 派生类的构造函数和析构函数5 多继承6 虚基类31 继承与派生的概念保持已有类的特性而构造新类的过程称为继承。在已有类的基础上新增自己的特性而产生新类的过程称为派生。被继承的已有类称为基类(或父类)。派生出的新类称为派生类。4继承与派生问题举例5继承与派生问题举例6继承与派生的目的继承的目的:实现代码重用。派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。7 派生类生成过程三个步骤:(1)吸收基类成员:除构造函数和析构函数外,新类
2、将基类的公有成员全部接受。(2)改造基类成员:在新类中通过继承方式来控制继承来成员的访问权限;在新类中定义与基类中同名的数据或函数,即“同名覆盖”,实现以新成员取代基类的成员;(3)添加新的成员:包括数据和函数。8 2 派生类的构成Person类char sname;int age;char sex;void display()基类数据成员成员函数Student类char sname;int age;char sex;void display()int num;int class;void display()继承派生类新增基类和派生类的关系9基类与派生类的对应关系单继承派生类只从一个基类派生。
3、多继承派生类从多个基类派生。多重派生由一个基类派生出多个不同的派生类。多层派生派生类又作为基类,继续派生新的类。103 派生类的继承方式不同继承方式的影响主要体现在:派生类成员对基类成员的访问权限通过派生类对象对基类成员的访问权限三种继承方式公有继承 public私有继承 private保护继承 protected11必须在类声明的头部指明它的基类以及继承方式(基类成员的访问属性),如public、private或者protected;继承方式必须且只能选择一个,缺省默认为private;派生类的声明方式12class : ;例: class A/ A类的成员 ;class B: public
4、 A / B类的成员 ;单继承定义格式13基类的成员可以有public(公有)、protected(保护)和private(私有)三种访问属性;基类的自身成员可以访问基类中任何其它成员,但是基类的对象只能访问基类的公有成员;3 派生类的继承方式14在派生类中,从基类继承来的成员,其访问属性由继承方式控制;不同的继承方式使得具有不同访问属性的基类成员在派生类中的访问属性也不同:包括派生类的新增成员对继承来的基类成员的访问,以及派生类外部,通过派生类对象对继承来的基类成员的访问。3 派生类的继承方式15公有继承(public)基类的public和protected成员的访问属性在派生类中保持不变,
5、但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象只能访问基类的public成员。例1 从point类公有派生出circle类。16私有继承(private)基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象不能直接访问基类中的任何成员。例2 将例1中的公有继承改成私有继承。
6、17保护继承(protected)基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象不能直接访问基类中的任何成员。18关于访问属性:继承方式基类成员在派生类中的访问属性派生类中的成员函数派生类的对象公有继承public protected privatepublic protected不可直接访问可访问基类中的公有成员和保护成员可访问基类和派生类中的公有成员私有继承public protec
7、ted privateprivate private不可直接访问可访问基类中的公有成员和保护成员不能访问基类中的所有成员保护继承publicprotected privateprotected protected不可直接访问可访问基类中的公有成员和保护成员不能访问基类中的所有成员194 派生类的构造、析构函数 派生类的构造函数基类的构造函数不被继承,派生类中需要声明自己的构造函数。声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化,自动调用基类构造函数完成。派生类的构造函数需要给基类的构造函数传递参数20 派生类的构造函数在两种情况下,必须定义派生类的构造函数:派生类
8、本身需要构造函数;在定义派生类对象时,其相应的基类对象需调用带有参数的构造函数。21简单的派生类只有一个基类,只有一级派生,且派生类的数据成员不包含其它类的对象;建立一个派生类对象时,构造函数的执行顺序是:(1) 调用基类的构造函数;(2) 执行派生类的构造函数体中的内容。简单派生类的构造函数22简单派生类的构造函数派生类名:派生类名(基类所需的形参,本类成员所需的形参):基类名(参数表) 本类成员初始化赋值语句;例3 简单派生类的构造函数。23如果一个类的数据成员包含其它类的对象,则该对象就称为内嵌对象成员;内嵌对象成员的初始化, 是在建立派生类对象时通过调用派生类的构造函数实现;有内嵌对象
9、成员的派生类的构造函数的语法形式: 派生类名:派生类名(总参数表):基类名(参数表), 子对象名(参数表) / 派生类中新增成员的初始化; 有内嵌对象成员时派生类的构造函数24参数总表:包括初始化基类数据、新增对象数据及新增一般成员所需的全部数据。建立派生类对象时,构造函数的执行顺序是:(1) 调用基类的构造函数;(2) 调用子对象的构造函数;(3) 执行派生类的构造函数体中的内容。例4 包含子对象的派生类的构造函数。有内嵌对象成员时派生类的构造函数25派生类构造函数的特殊形式(1) 派生类的构造函数可以是空函数;(2) 若在基类中没定义构造函数或定义了无参构造函数,则派生类构造函数的定义就不
10、写基类的构造函数。26派生类的析构函数在派生类中是否要定义析构函数与它所属的基类无关;派生类析构函数的定义与无继承关系的类的析构函数定义相同;系统会自动调用基类及对象成员的析构函数来对基类和对象成员进行清理,但执行次序和构造函数正好相反(先派生类,再基类对象,后基类)。例5 给出下列程序的输出结果。275 多继承一个派生类由多个基类派生而来,这种情况称为多继承。base1base2base3derive1derive2derive3derive428声明多继承的方法定义多继承派生类时,要指出它的所有基类名及继承方式;声明形式: class 派生类名:继承方式1 基类名1,继承方式2 基类名2,
11、 继承方式n 基类名n 派生类新增成员; 多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性与单继承的规则相同。29多继承派生类的构造函数多继承派生类的构造函数定义与单继承相似,但几个基类的构造函数之间用“,”分隔。形式如下:派生类名:派生类名(参数总表):基类1(参数表1),基类n(参数表n),对象成员1(参数表1),对象成员n(参数表n) /派生类新增成员的初始化语句; 30多继承派生类的构造函数派生类构造函数要完成新增构造函数的调用以及所有基类构造函数的调用;参数总表包含其后的各个分参数表,即构造函数的参数必须包含完成所有基类初始化以及内嵌对象初始化所需要所有参数,即参数总是分
12、配给后面的参数表1、参数表2,。31 多继承构造函数的执行顺序 先祖先(基类),调用基类构造函数,调用顺序按照它们被继承时说明的顺序(从左向右); 再客人(内嵌对象成员),调用内嵌对象的构造函数,调用顺序按照它们在类中说明的顺序; 后自己(派生类),执行派生类构造函数体中的内容 。32例6 多继承构造函数举例#include class B1/基类B1,构造函数有参数public:B1(int i) coutconstructing B1 iendl;class B2/基类B2,构造函数有参数public:B2(int j) coutconstructing B2 jendl;class B3
13、/基类B3,构造函数无参数public:B3()coutconstructing B3 *endl;class C: public B2, public B1, public B3 public:/派生类的公有成员C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b) private:/派生类的私有对象成员B1 memberB1;B2 memberB2;B3 memberB3;void main()C obj(1,2,3,4); 运行结果:constructing B2 2constructing B1 1const
14、ructing B3 *constructing B1 3constructing B2 4constructing B3 *3334C(int a,int b,int c,int d):B1(a),memberB2(d),memberB1(c),B2(b) 构造函数的参数表中给出了基类及内嵌成员对象所需的全部参数;在冒号之后调用各个基类及内嵌对象的构造函数;基类构造函数的执行顺序按照它们在派生类中声明继承的顺序(B2,B1,B3 );内嵌对象构造函数的执行顺序也按照其在派生类中声明的顺序( B1,B2,B3 ) 。例6 多继承构造函数举例35需要注意:1、在类C的构造函数中,没有列出全部基类
15、和内嵌成员对象,因B3类只有默认构造函数,不需传递参数,故基类B3以及B3类成员对象memberB3不必列出;2、在类C的构造函数中,基类名和成员对象名的顺序可随意。派生类构造函数体为空,实际上它只起到传递参数和调用基类和内嵌对象构造函数的作用。例6 多继承构造函数举例36多继承的析构函数析构函数也不被继承,派生类自行声明声明方法与一般(无继承关系时)类的析构函数相同。不需要显式地调用基类的析构函数,系统会自动隐式调用。析构函数的调用次序与构造函数相反。例7 多继承派生类的构造函数与析构函数。37例7 派生类析构函数举例#include class B1/基类B1声明 public:B1(in
16、t i) coutconstructing B1 iendl;B1() coutdestructing B1 endl;class B2/基类B2声明public:B2(int j) coutconstructing B2 jendl;B2() coutdestructing B2 endl;class B3/基类B3声明public:B3()coutconstructing B3 *endl;B3() coutdestructing B3 endl;class C: public B2, public B1, public B3public:C(int a, int b, int c, in
17、t d): B1(a),memberB2(d),memberB1(c),B2(b)private:B1 memberB1;B2 memberB2;B3 memberB3;void main()C obj(1,2,3,4); 3839运行结果constructing B2 2constructing B1 1constructing B3 *constructing B1 3constructing B2 4constructing B3 *destructing B3destructing B2destructing B1destructing B3destructing B1destruct
18、ing B240同名隐藏规则当派生类与基类中有相同成员时:若未强行指名,则通过派生类对象使用的是派生类中的同名成员。如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。41例8 多重继承同名隐藏举例#include class B1/声明基类B1 public:/外部接口int nV;void fun() coutMember of B1endl;class B2/声明基类B2 public:/外部接口int nV;void fun()coutMember of B2endl;class D1: public B1, public B2 public:int nV;/同名数据成员v
19、oid fun()cout“Member of D1”endl; 同名函数成员;void main()D1 d1;d1.nV=1; /对象名.成员名标识, 访问D1类成员d1.fun(); d1.B1:nV=2;/作用域分辨符标识, 访问基类B1成员d1.B1:fun();d1.B2:nV=3;/作用域分辨符标识, 访问基类B2成员d1.B2:fun();4243二义性问题在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性(不确定性)采用虚函数或同名隐藏规则来解决。当派生类由多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性采用虚基
20、类来解决。44二义性问题举例(一)class A public: void f();class B public: void f(); void g();class C: public A, piblic B public: void g(); void h();如果声明:C c1;则 c1.f(); 具有二义性而 c1.g(); 无二义性(同名覆盖)45二义性的解决方法解决方法一:用类名来限定c1.A:f() 或 c1.B:f()解决方法二:同名覆盖在C 中声明一个同名成员函数f(),f()再根据需要调用 A:f() 或 B:f()46二义性问题举例(二)class B public: int b;class B1 : public B private: int b1;class B2 : public B private: int b2;class C : public B1,public B2 public: int f(); private: int d;派生类C的对象的存储结构示意图:bb1bb2dB类成员B类成员B1类成员B2类成员C类对象有二义性:C c;c.bc.B:b无二义性:c.B1:bc.B2:b47486 虚基类虚基类的引入用于有共同基类的场合声明以virtual修饰说明基类例:class B1:virtual
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 印花丝织品加工项目招商计划书
- 年产xxx铁艺制品项目可行性研究报告(项目建议书)
- 年产xx实木复合底板基材项目可行性研究报告(项目规划)
- 浅谈室内设计风格演变发展与创新
- 黑河学院《油画半身像》2022-2023学年第一学期期末试卷
- 贺州学院《电子商务网站建设与管理》2021-2022学年第一学期期末试卷
- 菏泽学院《英语视听说》2021-2022学年第一学期期末试卷
- 菏泽学院《食品企业管理》2022-2023学年第一学期期末试卷
- 2024农场园区冬日研学冬令营(寻年记-冬日喜乐会主题)活动策划方案-35P
- 天然气燃烧排放物的环境监管与管理
- 能源管理系统EMS用户需求说明书
- 药理学-抗结核药物-课件
- 华为5G站点开通配置指导手册2023年
- 热处理工艺规程(工艺参数)
- 高龄津贴“免申即享”改革实施方案
- 人工智能导论 课件 项目1、2 人工智能的前世今生、人工智能基础
- 缓冲托辊说明书
- 安抚(氟比洛芬酯注射液)-泌尿外科术后疼痛管理的基础药物
- 国际专利分类(IPC)新版
- 110kV通衢变电站电气监理细则(正式)
- 初识无人机课件
评论
0/150
提交评论