C语言与程序设计大学教程(CPP教材第二版)三ppt.ppt_第1页
C语言与程序设计大学教程(CPP教材第二版)三ppt.ppt_第2页
C语言与程序设计大学教程(CPP教材第二版)三ppt.ppt_第3页
C语言与程序设计大学教程(CPP教材第二版)三ppt.ppt_第4页
C语言与程序设计大学教程(CPP教材第二版)三ppt.ppt_第5页
已阅读5页,还剩221页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2020 3 27 1 CPP教材 第二版 三 李龙澍著 C语言与程序设计大学教程 2020 3 27 2 第7章 继承第8章静态成员与友元第9章多态和虚函数 李龙澍著 2020 3 27 3 第7章 继承 本章要点 基类和派生类单继承多继承虚基类 2020 3 27 4 第7章继承 7 1基类和派生类7 2单继承7 3多继承7 4虚基类7 5例题分析和小结实训7习题 2020 3 27 5 第7章继承 面向对象程序设计中 可以在已有类的基础上定义新的类 而不需要把已有类的内容重新书写一遍 这就是继承 已有类称为基类或父类 在继承建立的新类称为派生类或导出类 子类 2020 3 27 6 第7章继承 继承性允许一个类从其它类中继承属性 如果一个对象从单个基类中继承了属性 就被称为单继承 如果一个对象从多个基类中继承了属性 就被称为多重继承 继承是面向对象的一个重要的概念 它同时也是面向对象程序设计中的一个有力的武器 较好地解决了代码重用问题 2020 3 27 7 7 1基类和派生类 基类和派生类是继承中的两个概念 被继承的类称为基类 由继承产生的新类称为派生类 7 1 1派生类的定义一个派生类可以看作是对现有类的继承或扩展 原有的类称为基类或父类 派生的类不仅具有基类的特征 而且还可以定义自己独有的特征 2020 3 27 8 7 1基类和派生类 C 中定义派生类的语法格式如下 class 新增私有成员声明语句列表public 新增公有成员声明语句列表protected 新增保护成员声明语句列表 继承方式决定了子类对父类的访问权限 有3种继承方式public private和protected 缺省为private 最常用的是public 2020 3 27 9 7 1基类和派生类 派生类的优点 使用派生类可以提高程序的效率 因为它支持代码重用 不需要建立一系列独立冗长的数据结构来处理所有数据的函数 而使用传统的数据结构 每处理一次都有不必要的重复信息 内存分配增多 相应的访问速度也会降低 而且程序还需要更多时间来判断表达式的正误和通过复杂的条件集来访问所需数据 派生类因为无需保存大量的冗余数据从而可以节省程序员的大量时间 2020 3 27 10 7 1基类和派生类 例7 1 圆Circle类继承点Point类 classPoint floatx y 点的坐标public Point floata 0 floatb 0 x a y b 点的构造函数voidSetP floata 0 floatb 0 x a y b voidDisplay cout 位置是 x y n 2020 3 27 11 7 1基类和派生类 classCircle publicPoint floatr 圆的半径public Circle floatz 1 floatx 0 floaty 0 Point x y 调用基类的构造函数 r z 圆自己的构造函数的函数体voidSetC floatz 1 floatx 0 floaty 0 r z SetP x y voidPrint cout 圆的 Display cout 圆的半径是 r endl 2020 3 27 12 7 1基类和派生类 voidmain Circlea 3 2 a Print a SetC 6 8 2 a Print 运行结果为 圆的位置是 0 0 圆的半径是 3 2圆的位置是 8 2 圆的半径是 6圆Circle类继承了点Point类的位置 实现了程序Point类的重用 2020 3 27 13 7 1基类和派生类 关于继承的几点说明 如果子类继承了父类 则子类自动具有父类的全部数据成员 数据结构 和成员函数 功能 但是 子类对父类的成员的访问有所限制 子类可以定义自己的成员 数据成员和成员函数 基类 派生类或父类 子类都是 相对 的 一个类派生出新的类就是基类 派生类也可以被其他类继承 这个派生类同时也是基类 2020 3 27 14 7 1基类和派生类 7 1 2继承方式继承类别 公有继承 私有继承 保护继承 公有继承派生时用 public 作继承方式 基类的公有段 public 成员被继承为公有的 基类的私有段 private 成员在派生类中不可见 基类的保护段 protected 成员被继承为保护的 私有继承派生时用 private 作继承方式 基类的公有段 public 成员被继承为私有的 基类的私有段 private 成员在派生类中不可见 基类的保护段 protected 成员被继承为私有的 2020 3 27 15 7 1基类和派生类 保护继承派生时用 protected 作继承方式 基类的公有段 public 成员被继承为保护的 基类的私有段 private 成员在派生类中不可见 基类的保护段 protected 成员被继承为保护的 2020 3 27 16 7 1基类和派生类 注意事项 1 无论哪种继承方式 基类中的private成员在派生类中都是不可见的 换句话说 基类中的private成员不允许外部函数或派生类中的任何成员访问 2 private派生确保基类中的方法只可以让派生类对象中的方法间接使用 而不能被外部使用 3 public派生使得派生类对象和外部都可以直接使用基类中的方法 除非这些方法已被重新定义 4 protected成员是一种血缘关系内外有别的成员 它对派生对象来说 是公开成员 可以访问 对血缘外部来讲 和private成员一样被隐蔽 2020 3 27 17 7 1基类和派生类 5 private派生使得基类的非私有成员都成为派生类中的私有成员 protected派生使基类中的非私有成员的访问属性在派生类中都降为保护的 public派生使得基类的非私有成员的访问属性在派生类中保持不变 不同继承方式的结果如表7 1 2020 3 27 18 7 1基类和派生类 表7 1派生类的继承访问属性 2020 3 27 19 7 2单继承 7 2 1继承成员的访问权限类中的成员有不同的访问权限 公有成员 一个类的公有成员允许本类的成员函数 本类的对象 公有派生类的成员函数 公有派生类的对象访问 私有成员 一个类的私有成员只允许本类的成员函数访问 保护成员 具有私有成员和公有成员的特性 对其派生类而言是公有成员 对其对象而言是私有成员 基类数据成员声明为保护的是有益的 派生类可以自由访问 外部不能访问 既实现信息重用 又做到了信息隐藏 2020 3 27 20 7 2单继承 例7 2 类的各种成员的访问权限 includeclassA inti 私有成员protected 保护成员intj voidfn1 cout 保护成员i i j j endl public 公有成员A intx inty i x j y voidfn2 成员函数可以访问保护成员 cout 公有成员i i j j endl fn1 2020 3 27 21 7 2单继承 voidmain Ax 21 63 x fn2 运行结果为 公有成员i 21j 63保护成员i 21j 63在主程序中只能访问公有成员 成员函数可以访问保护成员和私有成员 在例7 2中 只能通过函数fn2 访问函数fn1 不能在主程序中直接调用x fn1 2020 3 27 22 7 2单继承 例7 3 学校职工类的公有继承和私有继承 include includeclasspeople charname 10 sex 姓名 性别longidnumber 身份号码public people longnum 0 char n chars m 构造函数 idnumber num strcpy name n sex s voidp show cout 人员 编号 idnumber cout 姓名 name 性别 sex endl 2020 3 27 23 7 2单继承 classmember privatepeople 教工类私有继承people类 intm num 工号public chardepartment 10 部门member longn char na chars m intmn 0 char md 0 people n na s m num mn strcpy department md 构造函数voidm show cout 教工 t p show 访问基类的公有成员cout 教工编号 m num m num 单位 department endl 2020 3 27 24 7 2单继承 classworker publicmember 工人类公有继承类member charstation 10 岗位public worker longn char na chars m intmn 0 char md 0 char st 0 member n na s mn md strcpy station st 构造函数voidw show cout 工人 t m show 访问基类的公有成员cout 岗位 station endl endl 2020 3 27 25 7 2单继承 classteacher privatemember 教师类私有继承类member charcourse 10 执教课程public teacher longn char na chars m intmn 0 char md 0 char tc 0 member n na s mn md strcpy course tc 构造函数voidt show cout 教师 t m show 访问基类的公有成员cout 课程 course endl endl 2020 3 27 26 7 2单继承 voidmain workerw 123456 王祥 m 3761 生物系 实验室 w w show w m show worker类公有继承member 所以可以直接访问member类的公有成员 w p show member类私有继承people 不可以直接访问people类的公有成员teachert 661001 李辉 m 1954 计算机系 C t t show t m show teacher类私有继承member 不可以直接访问member类的公有成员 t p show teacher类私有继承member member私有继承people类 不可以直接访问people类的公有成员 2020 3 27 27 7 2单继承 类的继承关系如图7 1所示 类people是基类定义人的姓名 性别 身份号和对这3种数据的显示 类member私有继承people 定义了职工号 部门和信息显示 类member生成的对象不能直接访问类people中的任何成员 类worker公有继承类member 定义了岗位和信息显示 类worker生成的对象可以直接访问类member中的公有成员 类teacher私有继承类member 定义了执教课程和信息显示 类teacher生成的对象不能直接访问类member中的任何成员 2020 3 27 28 7 2单继承 2020 3 27 29 7 2单继承 运行结果为 工人教工人员 编号 123456姓名 王祥性别 m教工编号 m num 3761单位 生物系岗位 实验室教工人员 编号 123456姓名 王祥性别 m教工编号 m num 3761单位 生物系教师教工人员 编号 661001姓名 李辉性别 m教工编号 m num 1954单位 计算机系课程 C 2020 3 27 30 7 2单继承 例7 4 类的保护继承 includeclassA inti protected intj voidshow A1 cout A保护显示 i i j j endl public A intx inty i x j y voidshow A2 cout A2在执行show A1 show A1 cout A2执行完毕 endl 2020 3 27 31 7 2单继承 classB protectedA intx public B inti intj intk A i j x k voidshow B cout B在执行show A1 show A1 保护继承可以访问A的保护成员cout B公有显示 x x endl cout B执行完毕 endl 2020 3 27 32 7 2单继承 classC publicB public C inti intj intx B i j x 空语句voidshow C cout C在执行show A2 show A2 说明可以访问A2 A2是B的保护成员cout C在执行show A1 这两句是多余的 show A1 说明可以访问A1 A1也是B的保护成员cout C在执行show B show B cout C执行完毕 endl 2020 3 27 33 7 2单继承 voidmain Bb 1 2 3 b show B b show A2 B从A类保护继承 所以不能直接访问A类的公有成员Cc 100 200 300 c show C c show A2 C从B类公有继承 而B从A保护继承 所以不能直接访问A类的公有成员 2020 3 27 34 7 2单继承 表7 2列出了类例7 4中的继承属性 表7 2例7 4类的继承属性 2020 3 27 35 7 2单继承 运行结果为 B在执行show A1 A保护显示 i 1j 2B公有显示 x 3B执行完毕 C在执行show A2 A2在执行show A1 A保护显示 i 100j 200A2执行完毕 C在执行show A1 A保护显示 i 100j 200C在执行show B B在执行show A1 A保护显示 i 100j 200B公有显示 x 300B执行完毕 C执行完毕 2020 3 27 36 7 2单继承 7 2 2构造函数和析构函数在派生关系中 构造函数和析构函数是不能继承的 对派生类要重新定义构造函数和析构函数 因为一个派生类对象中也包含了基类数据成员的值 所以在声明一个派生类对象时 系统首先要通过派生类的构造函数调用基类中的构造函数 对基类成员初始化 然后对派生类中新增的成员初始化 也就是说 派生类的构造函数除了对新增成员进行初始化处理之外 还要调用基类的构造函数 2020 3 27 37 7 2单继承 在例7 1 例7 3和例7 4中 派生类的构造函数已经调用了基类的构造函数 一般来说 若X类派生出Y类 派生类Y中的构造函数的语法格式如下 Y Y ArgX1 ArgX2 ArgY1 ArgY2 X ArgX1 ArgX2 其中Y为派生类名 X为Y的直接基类名 ArgXi是X构造函数中的参数 ArgYi是Y构造函数中的参数 2020 3 27 38 7 2单继承 例7 5 声明一个派生类对象的实际操作步骤 设计基类 如要建立教工类 首先建立人员基类 classpeople charname 10 sex 姓名 性别longidnumber 身份号码public people longnum 0 char n chars m 构造函数 idnumber num strcpy name n sex s voidp show 显示函数 cout 人员 身份号 idnumber cout 姓名 name 性别 sex endl 2020 3 27 39 7 2单继承 设计派生类 classmember publicpeople 教工类公有继承people类 intm num 工号public chardepartment 10 部门member longn char na chars m intmn 0 char md 0 people n na s m num mn strcpy department md 构造函数voidm show cout 教工 t p show 访问基类的公有成员cout 教工编号 m num m num 单位 department endl 2020 3 27 40 7 2单继承 定义对象 声明派生类member类对象 memberw 123456 王一 m 789 计算机系 创建该类对象时 自动调用member类的构造函数 再由member类的构造函数调用基类people类的构造函数 首先执行的是基类people类的构造函数 创建它的成员 然后执行派生类member类的构造函数 从而创建它的成员 如图7 2所示 2020 3 27 41 7 2单继承 2020 3 27 42 7 2单继承 派生类的构造函数的构成形式和包含对象成员的类的构造函数相似而不相同 派生类的构造函数要直接调用基类的构造函数 在冒号后写的是基类的构造函数表达式 而包含对象成员的类的构造函数是要在构造函数中创建一个成员对象 冒号后边使用的是成员对象名和初始化参数 当派生类对象撤销时 析构函数调用的顺序和构造函数相反 先撤销派生类本身 再撤销其成员 最后撤销基类 每个类都有一个析构函数来释放类中使用的动态数据成员 类析构函数没有参数 不需要显式地在派生类中调用基类的析构函数 2020 3 27 43 7 2单继承 单继承中的构造函数和析构函数的应用说明 派生类的构造函数的初始化列表中列出的均是直接基类的构造函数 构造函数不能被继承 因此派生类的构造函数只能通过调用基类的某个构造函数 如果有重载的话 来初始化基类子对象 派生类的构造函数只负责初始化自己定义的数据成员 先调用基类的构造函数 再调用派生类自己的数据成员所属类的构造函数 最后调用派生类的构造函数 派生类的数据成员的构造函数被调用的顺序取决于在类中声明的顺序 析构函数不可以继承 不可以被重载 也不需要被调用 派生类的对象的生存期结束时自动调用派生类的析构函数 在该析构函数结束之前再自动调用基类的析构函数 所以 析构函数的被自动调用次序与构造函数相反 2020 3 27 44 7 2单继承 7 2 3单继承的应用以教师和学生信息管理为例 简单介绍单继承的使用 例7 6 设计表示学校教师 职工和学生的类及其继承关系 2020 3 27 45 7 2单继承 include includeclasspeople charname 10 sex 姓名 性别longidnumber 身份号码public people longnum 0 char n chars m 构造函数 idnumber num strcpy name n sex s voidp show cout 人员 身份号 idnumber cout 姓名 name 性别 if sex m sex M cout 男 endl if sex w sex W cout 女 endl 2020 3 27 46 7 2单继承 classstudent publicpeople 学生类公有继承people类 ints num 学号public ints class 班级student longn char na chars m intsn 0 intsc 0 people n na s s num sn s class sc 构造函数voids show cout 学生 t p show cout 学号 s num 班级 s class endl 2020 3 27 47 7 2单继承 classmember publicpeople 教工类公有继承people类 intm num 工号public chardepartment 10 部门member longn char na chars m intmn 0 char md 0 people n na s m num mn strcpy department md 构造函数voidm show cout 教工 t p show 访问基类的公有成员cout 教工编号 m num 单位 department 2020 3 27 48 7 2单继承 classworker publicmember 工人类公有继承类member charstation 10 岗位public worker longn char na chars m intmn 0 char md 0 char st 0 member n na s mn md strcpy station st 构造函数voidw show cout 工人 t m show 访问基类的公有成员cout t岗位 station endl 2020 3 27 49 7 2单继承 classteacher publicmember 教师类公有继承基类member charcourse 10 执教课程public teacher longn char na chars m intmn 0 char md 0 char tc 0 member n na s mn md strcpy course tc 构造函数voidt show cout 教师 t m show 访问基类的公有成员cout t执教课程 course endl 2020 3 27 50 7 2单继承 voidmain peoplep 981102 赵一 w p p show students 781010 钱二 m 1001 982 s s show workerw 123456 孙三 m 123 计算机系 秘书 w w show teachert 661001 李四 m 456 计算机系 C t t show cout 直接访问公有基类的公有成员 endl t m show 公有继承的派生类对象直接访问基类的公有成员t p show 公有继承的派生类对象直接访问基类的基类的公有成员cout t department endl 直接访问基类的公有数据成员 2020 3 27 51 7 2单继承 2020 3 27 52 7 2单继承 在例7 6中所有的继承全是公有继承 在派生类中 最一般的继承就是公有继承 运行结果为 人员 身份号 981102姓名 赵一性别 女学生人员 身份号 781010姓名 钱二性别 男学号 1001班级 982工人教工人员 身份号 123456姓名 孙三性别 男教工编号 123单位 计算机系岗位 秘书教师教工人员 身份号 661001姓名 李四性别 男教工编号 456单位 计算机系执教课程 C 直接访问公有基类的公有成员 教工人员 身份号 661001姓名 李四性别 男教工编号 456单位 计算机系人员 身份号 661001姓名 李四性别 男计算机系 2020 3 27 53 7 3多继承 7 3 1多继承的概念多继承是由多个基类派生出新的类 多继承机制如图7 4所示 2020 3 27 54 7 3多继承 类class D继承class A class B class C三个基类 类class D是类class A class B class C的派生类 类class D包含类class A class B class C的所有数据成员和成员函数 2020 3 27 55 7 3多继承 多继承派生类的语法格式如下 class 在多继承中 若基类的成员有重名的 使用这个成员时 要加基类名和作用域运算符 来指明是哪个类的成员 例如 Class A Class B和Class C都有公有变量x 在派生类Class D使用基类的变量x 要分别写作 Class A x Class B x Class C x 在派生类Class D的对象Obj中 使用基类的变量x 要分别写作 Obj Class A x Obj Class B x Obj Class C x 2020 3 27 56 7 3多继承 例7 7 一个简单的多继承 includeclassA inti public A intii 0 i ii voidshow cout A show A中i i endl classB inti public B intii 0 i ii voidshow cout B show B中i i endl 2020 3 27 57 7 3多继承 classC publicA publicB inti public C intiA 0 intiB 0 intiC 0 A iA B iB i iC voidshow cout C show C中i i endl voidmain Cc 1 2 3 c A show 调用对象c的基类A的成员函数show c B show 调用对象c的基类B的成员函数show c show 调用对象c所属的类C的成员函数show 2020 3 27 58 7 3多继承 运行结果为 A show A中i 1B show B中i 2C show C中i 3 2020 3 27 59 7 3多继承 7 3 2多继承的构造函数多基派生类的构造函数的一般形式为 参数表1 参数表2 若基类使用无参构造函数时 可以将基类的构造函数省略 基类的构造函数必须是已定义的 多重继承的构造函数按照下面的原则被调用 先基类 后自己 在同一层上如有多个基类 按派生时定义的先后次序执行 2020 3 27 60 7 3多继承 7 3 3多继承的应用多继承有普遍的应用 如客货两用车 具有客车的特征 也具有货车的特征 西红柿具有水果的特征 也具有蔬菜的特征 青蛙具有陆地动物的特征 也具有水中动物的特征 这些都是生活中的多继承 例7 8 西红柿的多继承 定义水果和蔬菜2个类作为基类 西红柿作为派生类 classfruit 定义水果类public print cout 直接食用 味道鲜美 endl 2020 3 27 61 7 3多继承 classvegetable 定义蔬菜类public print cout 烧炒烹炸 餐桌佳肴 endl classtomato publicfruit publicvegetable 定义西红柿类public print cout 西红柿 酸甜可口 endl voidmain tomatot t print t fruit print t vegetable print 2020 3 27 62 7 3多继承 运行结果为 西红柿 酸甜可口 直接食用 味道鲜美 烧炒烹炸 餐桌佳肴 2020 3 27 63 7 4虚基类 7 4 1虚基类的定义在多继承中 若在多条继承路径上 有公共基类 这个公共基类便会产生多个副本 为了解决这个问题 把公共基类定义为虚基类 使用虚基类的继承称为虚拟继承 虚基类是对派生类而言 所以 虚基类本身的定义同基类一样 在定义派生类时声明该基类为虚基类即可 就是冠以关键字 virtual 虚基类在定义由基类直接派生的类时说明 说明的语法格式为 class virtual 2020 3 27 64 7 4虚基类 例7 9 一个虚基类继承的例子 includeclassA public voidfn cout A fn endl classB1 virtualpublicA 虚拟继承public voidfn cout B1 fn endl classB2 virtualpublicA 虚拟继承public voidfn cout B2 fn endl 2020 3 27 65 7 4虚基类 classC1 publicB1 classC2 publicB2 classD publicC1 publicC2 voidmain Dobj obj C1 fn obj C2 fn obj A fn 可以执行 无二义性 2020 3 27 66 7 4虚基类 若类A不是虚基类语句obj A fn 就不能执行 这是因为计算机无法确定是执行B1继承的基类A的函数 还是执行B2继承的基类A的函数 具有二义性 A为虚基类就只有一个基类副本 运行结果为 B1 fn1 B2 fn1 A fn 2020 3 27 67 7 4虚基类 若基类使用无参构造函数时 可以将基类的构造函数省略 基类的构造函数必须是已定义的 对于例7 9 A是否为虚基类 程序结构不一样 如图7 5所示 2020 3 27 68 7 4虚基类 多重继承的构造函数按照下面的原则被调用 1 先基类 后派生类 2 在同一层上如有多个基类 则先虚基类 后非虚基类 3 在同一层上如有多个虚基类 则按派生时定义的先后次序执行 在同一层上如有多个非虚基类 则按派生时定义的先后次序执行 4 对于一个派生类的某个虚基类的构造函数一旦被执行过 就不再被多次执行 也就是虚基类的构造函数只能执行1次 5 虚基类的派生类的构造函数的定义无特殊规定 6 如果虚基类的直接派生类的构造函数的初始化列表中不调用虚基类的构造函数 则该派生类的虚基类的构造函数必须是无参的 或全部是缺省值的构造函数 2020 3 27 69 7 4虚基类 7 4 2虚基类的构造函数首先通过一个例子来认识虚基类的构造函数和用法 例7 10 虚基类的构造函数 include includeclassbase charname 15 public base char m 王五 strcpy name m voidshow cout base输出 name endl 2020 3 27 70 7 4虚基类 classbase1 virtualpublicbase public base1 char m base m classbase2 virtualpublicbase public base2 char m base m 2020 3 27 71 7 4虚基类 classderive virtualpublicbase1 publicbase2 charname 15 public derive char char char char derive char char char voidshowD cout derive输出 name endl derive derive char p char q char r char t base p base1 q base2 r strcpy name t derive derive char p char q char r base1 p base2 q strcpy name r 2020 3 27 72 7 4虚基类 voidmain derived 赵易 钱耳 孙伞 李思 d show d showD derivec 赵易 钱耳 孙伞 c show c showD base1b 周武 b show 运行结果为 base输出 赵易derive输出 李思base输出 王五derive输出 孙伞base输出 周武 2020 3 27 73 7 4虚基类 derive类把base1和base2当做它的基类 通过声明base1和base2为虚基类而解决了用base进行多次继承的问题 当derive的构造函数调用基类构造函数时 它必须直接调用base的构造函数 对象c使用derive char char char 构造函数没有直接调用base的构造函数 它也不再通过base1或者base2调用构造函数 而是自动调用base的默认参数构造函数 只有最远派生类的构造函数才会调用虚基类的构造函数 使用一个虚基类时 最远派生类的构造函数的职责是对虚基类进行初始化 这意味着该类不管离虚基类多远 都有责任对虚基类进行初始化 2020 3 27 74 7 4虚基类 7 4 3虚基类的应用虚基类实现了程序的动态连接 给编写程序带来了方便 例7 11 设计一个表示在职学生的类 先设计一个基类people表示一般人员的基本信息 再设计一个表示工作人员的类job 还要设计一个表示学生的类student 以这些类作为基类派生出在职学生类 2020 3 27 75 7 4虚基类 图7 6 a 表明了在职学生类的层次结构 people是一个虚基类 所以它只有一个副本 若people是一个非虚基类 则结果如图7 6 b 出现2个people副本 这是不符合题目原意的 2020 3 27 76 7 4虚基类 程序如下 include includeclasspeople charname 10 sex 姓名 性别longidnumber 身份号码public people longnum 0 char n chars m 构造函数 idnumber num strcpy name n sex s voidp show cout 人员 身份号 idnumber cout 姓名 name 性别 if sex m sex M cout 男 endl if sex w sex W cout 女 endl 2020 3 27 77 7 4虚基类 classjob virtualpublicpeople 工作人员类公有继承people虚基类 intm num 工号chardepartment 10 单位public job longn char na chars m intmn 0 char md 0 people n na s m num mn strcpy department md 构造函数voidm show cout 工作人员 cout 编号 m num 单位 department 2020 3 27 78 7 4虚基类 classstudent virtualpublicpeople 学生类公有继承people虚基类 ints num 学号ints class 班级public student longn char na chars m intsn 0 intsc 0 people n na s s num sn s class sc 构造函数voids show cout 在校学生 cout 学号 s num 班级 s class endl 2020 3 27 79 7 4虚基类 classjob student publicjob publicstudent public job student longn char na chars m intmn 0 char md 0 intNo 0 intsta 1 job n na s mn md student n na s No sta people n na s 构造函数voidt show cout 在职学生 endl 2020 3 27 80 7 4虚基类 voidmain job studentw 123456 赵一 m 123 商场 456 2002 w t show w p show w s show w m show cout endl 2020 3 27 81 7 4虚基类 运行结果为 在职学生人员 身份号 123456姓名 赵一性别 男在校学生学号 456班级 2002工作人员编号 123单位 商场 2020 3 27 82 7 5例题分析和小节 7 5 1例题 例7 12 给出下面程序的运行结果 includeclassbasescore intmath protected inteng public intchem 2020 3 27 83 7 5例题分析和小节 classdbase1 publicbasescore 公有继承public voidinput cout eng cout chem voidoutput cout 英语成绩 eng endl cout C 成绩 chem endl 2020 3 27 84 7 5例题分析和小节 classdbase2 privatebasescore 私有继承public voidinput cout eng cout chem voidoutput cout 英语成绩 eng endl cout C 成绩 chem endl 2020 3 27 85 7 5例题分析和小节 voidmain dbase1pub pub input 输入英语成绩和C 成绩dbase2pri pri input 输入英语成绩和C 成绩ints pub chem 读取公有继承的C 成绩cout s endl pub output pri output 2020 3 27 86 7 5例题分析和小节 运行结果为 输入英语成绩 82输入C 成绩 87输入英语成绩 91输入C 成绩 9587英语成绩 82C 成绩 87英语成绩 91C 成绩 95 2020 3 27 87 7 5例题分析和小节 7 5 2例题分析在C 中语言中 一个派生类可以从一个基类派生 也可以从多个基类派生 从一个基类派生的继承称为单继承 从多个基类派生的继承称为多继承 公有继承 私有继承和保护继承是常用的三种继承方式 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时 它们都保持原有的状态 而基类的私有成员仍然是私有的 basescore中的math在派生类中是不能访问的 2020 3 27 88 7 5例题分析和小节 私有继承的特点是基类的公有成员和保护成员都为派生类的私有成员 而且不能被这个派生类的子类所访问 但是可以被派生类的成员函数访问 如eng和chem 可以被派生类的成员函数output 访问 保护继承的特点是基类的公有成员和保护成员都为派生类的保护成员 而且只能被它的派生类成员函数或友元访问 基类的私有成员仍然是私有的 2020 3 27 89 7 5例题分析和小节 例7 12首先定义了基类basescore dbase1和dbase2是basescore的派生类 在派生类dbase1中 chem是公有的 可以用main的类对象访问 如s pub chem 在派生类dbase2中 chem变为私有的 不能用main的类对象访问 2020 3 27 90 7 5例题分析和小节 7 5 3小结本章探讨了C 类的继承问题 引进了基类和派生类的概念 基类就是一种普通的类 任何一个类 若被其他类继承 这个类就是基类 派生类是继承基类的类 派生类包含基类所有的信息 但是又有自己独特的内容 2020 3 27 91 7 5例题分析和小节 类中成员的访问权限有三种 公有成员在任何地方都能访问 私有成员只有本类中的成员函数可以访问 保护成员只有本类中的或派生类中的成员函数可以访问 有三种派生 公有派生对基类的访问权限不变 私有派生对基类的访问完全变为私有的 保护对基类的非私有访问权限变为保护的 基类的私有成员任何派生类都是不可见的 2020 3 27 92 7 5例题分析和小节 单继承是只有一个基类派生的继承 多继承是由多个基类同时派生一个派生类 虚基类使一个基类不论在多继承中出现几次 最终只有一个副本 可以避免基类的重复定义 通过对本章的学习 可以对类的派生有一个系统的了解 学会使用继承编写程序 2020 3 27 93 实训7人员类的继承 1 实训题目首先设计一个人员类person作为基类 其数据成员为姓名和身份号 成员函数有输入数据和显示数据 再设计一个学生地址类add 包括数据成员地址和年龄 成员函数有输入数据和显示数据 生成person的派生类学生student student包括数据成员电话号码和C 成绩 成员函数也是有输入数据和显示数据 设计学生成绩类score 它是student类和add类的派生类 继承2个类的所有属性 score类本身有数据成员数学成绩和英语成绩 当然成员函数也有输入数据和显示数据 职员类employee继承person类 类中没有任何成员 并且编写主程序观察运行结果 2020 3 27 94 实训7人员类的继承 2 实训要求 1 建成人员类person 2 建成地址类add 3 由person类派生出student类 4 由person类派生出employee类 5 由student类和add类共同类派生出学生成绩类score 6 编制主程序 7 运行主程序观察运行结果 2020 3 27 95 习题7 7 1派生类构造函数执行的次序是怎样的 7 2C 中继承分为哪两类 继承方式又分为哪三种 7 3给出下面程序的运行结果 classincount intc1 c2 public incount c1 0 c2 1000 incount intvc1 intvc2 c1 vc1 c2 vc2 voidretcount void cout c1 c1 c2 c2 endl incountoperator c1 c2 returnincount c1 c2 2020 3 27 96 习题7 voidmain incountic1 ic2 ic1 retcount ic2 retcount ic1 ic1 retcount ic2 ic1 ic2 retcount 2020 3 27 97 习题7 7 4给出下面程序段的运行结果 classincount protected intc1 c2 public incount intvc1 0 intvc2 1000 c1 vc1 c2 vc2 voidretcount void cout c1 c1 cout c2 c2 endl incountoperator c1 c2 returnincount c1 c2 2020 3 27 98 习题7 classdncount publicincount public dncount intvc1 0 intvc2 1000 incount vc1 vc2 incountoperator c1 c2 returnincount c1 c2 voidmain dncountdc1 dc2 dc1 retcount dc2 retcount dc1 dc1 retcount dc2 dc2 retcount 2020 3 27 99 习题7 7 5如果派生类B中已经重载了基类A的一个成员函数fn1 没有重载基类A的成员函数fn2 如何调用基类的成员函数fn1 和fn2 2020 3 27 100 习题7 7 6给出下面程序的运行结果 constMAX 500 classqueue protected intq MAX intrear front public queue rear 0 front 0 cout 队列初始化 n voidqinsert inti rear q rear i cout rear rear endl 2020 3 27 101 习题7 intqdelete front cout front front endl returnq front 2020 3 27 102 习题7 classqueue2 publicqueue public voidqinsert inti if rear MAX queue qinsert i else cout 队列已满 n return intqdelete if front rear returnqueue qdelete else cout 队列溢出 n return0 2020 3 27 103 习题7 voidmain queue2a a qinsert 327 a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论