版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 第10章 承继和派生类 目的与要求10.1 承继与派生10.2 冲突、支配规那么和赋值兼容性10.3 虚基类10.4 静态数据成员本章小结目的与要求 经过本章学习,应了解承继与派生的概念,掌握派生类的定义语句格式及运用方法。知道基类成员经公有或私有派生后在派生类中的访问权限。初步掌握冲突、支配规那么、赋值兼容性的概念。了解虚基类的概念、虚基类的语句定义格式及运用方法。了解静态成员的定义格式、初始化方式及作用域。10.1 承继与派生 承继:从已有类出发建立新的类,使新类部分或全部地承继已有类的成员。 派生:经过承继已有的一个或多个类产生一个新类称为派生。 10.1.1 承继与派生的根本概念1承
2、继与派生的定义 在定义类B时,假设运用类A的部分或全部成员,那么称类B承继了类A,并称类A为基类或父类,称类B为派生类或子类。基类与派生类或父类与子类的关系可以用图表示。基类(父类) A派生类(子类)B承继与派生2单一承继 假设派生类是由一个基类派生出来的,称为单一承继,如派生类Score是由一个基类Student派生出的,所以为单一承继。如下图。 基类(父类) Student派生类(子类)Score单一承继3多重承继 假设派生类由多个基类派生出,称为多重承继。如下图。 多重承继基类(父类) Student基类(父类)Score派生类(子类)Information10.1.2 派生类的定义 1
3、.定义派生类的格式 class : , ; 阐明:1派生类由n个基类多重派生,当n=1时为单一承继。2访问权限access=public、private与protected2公有派生 假设在定义派生类时,access为public,那么定义公有派生。公有派生时,基类中一切成员在派生类中坚持各个成员的访问权限。详细访问权限如下:1基类中public成员在派生类仍坚持为public成员,所以在派生类内、外都可直接运用这些成员。2基类中private成员属于基类私有成员,所以在派生类内、外都不能直接运用这些成员。只能经过该基类公有或维护成员函数间接运用基类中的私有成员。公有派生3基类中protect
4、ed成员可在派生类中直接运用,但在派生类外不可直接访问这类成员,必需经过派生类的公有或维护成员函数或基类的成员函数才干访问。 【例10.1】 用学生档案类Student派生出学生成果类Score。讨论基类中公有、私有与维护数据成员在派生类中访问权限的变化。 例程3私有派生 假设在定义派生类时,access为private那么定义了私有派生。经过私有派生后:1基类中公有成员在派生类变为私有成员,在派生类内可以运用,而在派生类外不能直接运用。2基类中维护成员在派生类变为私有成员,在派生类内可以运用,而在派生类外不能直接运用。3基类中私有成员在派生类内、外都不能直接运用,必需经过基类公有函数运用。1
5、0.1.3 派生类的构造函数与基类成员的初始化 1.派生类构造函数格式 派生类的构造函数由初始化基类数据成员构造函数与初始化派生类新增的数据成员构造函数组成。派生类构造函数的格式为: :(形参表):(实参表1),(实参表n) 派生类构造函数体 派生类构造函数格式阐明:1基类构造函数实参可以是表达式或派生类构造函数的形参。 2实参只与形参名有关,而与参数顺序无关。 3冒号后基类构造函数列表称为初始化成员列表。 派生类构造函数举例【例10.2】多重派生实例。定义描画圆的类Circle,定义描画高的类High,用描画圆的类与描画高的类作为基类,多重派生出圆柱体类Cylinder。讨论多重承继中基类成
6、员的初始化问题。 例程2建立对象时,构造函数的调用顺序 先调用基类构造函数,再调用派生类构造函数。留意: 1在派生类中并不能直接对基类的私有数据成赋初始值,必需经过公有的构造函数进展初始化任务。 2基类构造函数的调用顺序取决于它们在派生类中阐明顺序,而与它们在派生类构造函数中的顺序无关。 3吊销对象时,析构函数的调用顺序 在吊销派生类的对象时,析构函数的调用顺序正好与构造函数的顺序相反。即:先调用派生类的析构函数,再调用基类析构函数。 【例10.3】定义两个基类Base1与Base2,并由Base1与Base2派生出派生类Derive。编写程序,输出派生类中构造函数与析构函数的调用关系。 例程
7、4派生类中包含对象成员的构造函数 假设派生类中包含对象成员,那么在派生类构造函数的初始化成员列表中不仅要列举要调用的基类构造函数,而且要列举调用的对象成员构造函数。 【例10.4】将例10.3的派生类改为包含对象成员的派生类。 例程 首先要调用基类的构造函数,再调用对象成员的构造函数,最后执行派生类的构造函数。在有多个对象成员的情况下,调用这些对象成员的构造函数的顺序取决于它们在派生类中阐明顺序。 10.2 冲突、支配规那么和赋值兼容性 10.2.1冲突 引例: 【例10.5】在例10.2中将描画高的类改为描画矩形的类Rectangle,在Rectangle类中用矩形中心坐标(x,y)、高(H
8、igh)与宽(Width)作为类的数据成员。 例程 冲突:派生类运用基类中同名成员时出现不独一称为冲突。处理方法:运用作用域运算符“:指明同名成员属于哪一个基类,即: :冲突结论: 假设一个公有派生类是由两个或多个基类派生,当基类中成员的访问权限为public或protected且不同基类中的成员同名时,派生类运用到基类中的同名成员时出现不独一性称为冲突。 处理方法是运用作用域运算符指明发生冲突的成员属于哪个基类。10.2.2 支配规那么 所谓支配规那么是指,当派生类中成员与基类中成员同名时,在不用作用域运算符时,派生类成员名优于基类成员名。 【例10.6】在【例10.5 】的派生类Cylin
9、der中,新增数据成员(x,y,z)表示圆柱体中心坐标。并从基类Rectangle中删除(x,y)。 例程 留意:当派生的成员名与基类的成员名一样时,在派生类中或派生类外要运用基类中的这种成员时,仍要运用作用域运算符。10.2.3 赋值兼容规那么 公有派生类的对象可赋给其基类对象,基类对象不能赋给派生类对象的规那么,称为赋值兼容规那么。 10.2.4 基类和对象成员的几点阐明 1任一基类在派生类中只能承继一次。2基类成员与对象成员在运用上的差别 派生类中可直接运用基类的成员访问权限 允许的话; 运用对象成员时,必需在对象名后加上成员运算符“.和成员名。 10.3 虚基类 10.3.1 多重派生
10、的基类拷贝 假设类B与类C由类A公有派生,而类D由类B与类C公有派生,那么类D中将包含类A的两个拷贝(如下图)。这种同一个基类在派生类中产生多个拷贝不仅多占用了存储空间,而且能够会呵斥多个拷贝数据的不一致。基类A基类A基类B基类C派生类D派生类中包含同一基类的两个拷贝多重派生的基类拷贝【例10.7】一个公共基类在派生类中产生两个拷贝。 例程 假设在多条承继途径上有一个公共的基类,那么该基类会在这些途径中的某几条途径的集合处产生几个拷贝。为使这样的公共基类只产生一个拷贝,须将该基类阐明为虚基类。 10.3.2 虚基类 在多重派生的过程中,欲使公共的基类在派生中只有一个拷贝,可将此基类阐明成虚基类
11、。 虚基类的定义格式为: class :virtual ; 或 class : virtual ;【例10.8】定义虚基类,使派生类中只需基类的一个拷贝。例程10.4 静态数据成员 将类的某一个数据成员的存储类型定义为静态类型时,那么由该类所产生的一切对象均共享为静态成员所分配的一个存储空间。 1静态数据成员的定义与援用方法在类中对静态数据成员作援用性阐明 static ;在类外文件作用域对静态数据成员作定义性阐明 必需在类外的文件作用域中,且只能作一次定义性阐明,并分配 内存空间。 :=初值; 定义性阐明时,静态数据成员缺省初值为0。 静态数据成员援用格式 : 静态数据成员 2同类不同对象的
12、静态数据成员占用一样的存储空间 。3静态数据成员置初值不受访问权限的限制。 4为了坚持静态数据成员取值的一致性,通常在构造函数中不给静态数据置初值,而是在静态数据成员的定义性阐明时指定初值。 本章小结 1.承继 承继:从已有类出发建立新的类,使新类部分或全部地承继已有类的成员称为承继。 派生:经过承继已有的一个或多个类产生一个新类称为派生。 派生类的定义格式如下: class : , , 派生类体; 基类成员在派生类中访问权限基类成员访问权限 公有派生后的访问权限 私有派生后的访问权限publicpublicprivateprivate不可直接访问不可直接访问protectedprivatep
13、rivate 公有或私有派生后基类成员在派生类中访问权限 派生类构造函数和析构函数 由于派生类成员由基类成员与派生类中新添加的成员组成,所以初始化任务应分为对派生类中新增成员的初始化与基类成员的初始化。由于初始化任务是由构造函数完成的,所以初始化基类成员的任务是由派生类的构造函数来完成的。 派生类构造函数的格式如下: :(形参表):(实参表1) (实参表n) ; 构造函数的调用顺序是先基类后派生类,析构函数的调用顺序是先派生类后基类。 2冲突、支配和赋值兼容性 冲突:派生类运用基类中同名成员时出现不独一称为冲突。冲突的处理方法: : 支配规那么:运用派生类中与基类中同名成员时,派生类成员优于基
14、类同名成员的规那么称为支配规那么。 赋值的兼容性:派生类对象可赋值给基类对象,基类对象不能赋给派生类对象称为赋值的兼容性。 3虚基类 在多重派生的过程中,欲使公共的基类在派生类中只需一个拷贝,可将此基类阐明成虚基类。虚基类的定义格式为: class :virtual ; 或 class : virtual ; 4静态数据成员 静态数据成员的定义必需分两步完成,在类内作援用性阐明,在类外作定义性阐明。阐明与援用格式为: 类内作援用性阐明的格式: static ; 类外作定义性阐明的格式: :=初值; 援用格式: :例10.11# include class Student private: in
15、t No; /定义No为私有数据成员 protected: int Age; /定义Age为维护的数据成员 public: char Sex; /定义Sex为公有数据成员 Student(int no,int age,char sex) /定义类Student的构造函数 No=no;Age=age;Sex=sex; int GetNo( ) return No; /前往No的公有成员函数 int GetAge( ) return Age; /前往Age的公有成员函数 void ShowS( ) /显示No、Age、Sex的公有成员函数 coutNo=NotAge=AgetSex=Sexendl
16、; ; 例10.12class Score : public Student /由基类Student公有派生出子类Score private: int Phi,Math; /定义类Score的私有数据成员 public: Score(int n,int a,char s,int p,int m):Student(n,a,s) /类Score的构造函数 Phi=p;Math=m; void Show( void) /显示类Score与其父类Student的数据成员值 coutNo=GetNo( )tAge=AgetSex=Sex tPhi=PhitMath=Mathendl; ;例10.13vo
17、id main(void) Score s (101,20,M,90,80); /用类Score定义一个对象s s.ShowS( ); /类Score的对象s调用基类公有函数 ShowS() s.Show( ); /类Score的对象调用公有函数Show()coutNo=s.GetNo( )tAge=s.GetAge()tSex=s.Sexendl; 程序执行后输出: No=101 Age=20 Sex=M No=101 Age=20 Sex=M Phi=90 Math=80 No=101 Age=20 Sex=M前往例10.21 # include class Circle /定义描画圆的类
18、,其中(x,y)为圆心,r为半径 protected: float x,y,r; public: Circle(float a,float b,float c) x=a;y=b;r=c;class High /定义描画高的类 private: float h; public: High(float a) h=a; float Geth( ) return h; 例10.22class Cylinder:public Circle,private High /由圆与高派生出圆柱体类 private: float Volume; public: Cylinder(float a,float b,f
19、loat c,float d):Circle(a,b,c),High(d) /D Volume=r*r*3.1415*Geth( ); /E void Show() coutx=xty=ytr=rt h=Geth()tV= Volumeendl; ;例10.23void main (void) Cylinder cy(3,3,2,10); cy.Show(); 程序执行后输出:x=3 y=3 r=2 h=10 V=125.664 前往例10.31# include class Base1 /定义基类Base1 private: int x; /定义基类Base1的私有数据成员x public:
20、 Base1(int a) /基类Base1的构造函数 x=a; cout调用基类1的构造函数!endl; Base1( ) /基类Base1的析构函数 cout调用基类1的析构函数!endl;例10.32class Base2 /定义基类Base2 private: int y; /定义基类Base2的私有数据成员y public: Base2(int a) /基类Base2的构造函数 y=a; cout调用基类2的构造函数!endl; Base2( ) /基类Base2的析构函数 cout调用基类2的析构函数!endl; 例10.33class Derive:public Base1,pu
21、blic Base2 /派生类Derive private: int z; /派生类Derive新增的私有数据成员 public: Derive(int a,int b):Base1(a),Base2(20) /派生类Derive构造函数 z=b; cout调用派生类构造函数!endl; Derive( ) /派生类Derive的析构函数 cout调用派生类的析构函数!endl; ;void main(void) Derive c(100,200); 例10.34程序执行后输出: 调用基类1的构造函数! 调用基类2的构造函数! 调用派生类的构造函数! 调用派生类析构函数! 调用基类2的析构函数
22、! 调用基类1的析构函数! 前往例10.41class Derive:public Base1,public Base2 private: int z; Base1 b1,b2; /在派生类中定义基类对象成员b1,b2 public: Derive (int a,int b):Base1(a),Base2(20),b1(200),b2(a+b) /定义构造函数 z=b; cout调用派生类的构造函数!endl; Derive ( ) cout调用派生类的析构函数!endl;void main(void) Derive d(100,200); 例10.42执行程序后输出: 调用基类1的构造函数!
23、 调用基类2的构造函数! 调用基类1的构造函数! 调用基类1的构造函数! 调用派生类的构造函数! 调用派生类的析构函数! 调用基类1的析构函数! 调用基类1的析构函数! 调用基类2的析构函数! 调用基类1的析构函数! 前往例10.51# include class Circle /定义描画圆的基类 protected: float x,y,r;/(x,y)为圆心,r为半径 public: Circle(float a,float b,float c) x=a;y=b;r=c; float Area( ) return (r*r*3.14159); /计算圆的面积;例10.52class Rec
24、tangle /定义描画矩形的基类 protected: float x,y,h,w; public: Rectangle(float a, float b, float c, float d) x=a;y=b;h=c;w=d; float Area(void) /计算矩形面积 return h*w; ;例10.53class Cylinder:public Circle,public Rectangle /描画一个圆柱体的派生类 private: float Volume; /圆柱体的体积 public: Cylinder(float a,float b,float c):Circle(a,
25、b,c),Rectangle(10,10,c,c) /A Volume=Area( )*h; /B float GetV( )return Volume; void Show(void) coutx=xty=yendl;/C;例10.54 void main (void) Cylinder cy(3,3,2); cy.Show();coutVolume=cy.GetV()endl;程序执行后输出: x=3 y=3 Volume=25.1327 前往例10.55# include class Circle /定义描画圆的基类 protected: float x,y,r;/(x,y)为圆心,r为
26、半径 public: Circle(float a,float b,float c) x=a;y=b;r=c; float Area( ) return (r*r*3.14159); /计算圆的面积;例10.56class Rectangle /定义描画矩形的基类 protected: float x,y,h,w; public: Rectangle(float a, float b, float c, float d) x=a;y=b;h=c;w=d; float Area(void) /计算矩形面积 return h*w; ;例10.57class Cylinder:public Circ
27、le,public Rectangle/描画一个圆柱体的派生类 private: float Volume; /圆柱体的体积 public: Cylinder(float a,float b,float c):Circle(a,b,c),Rectangle(10,10,c,c) /D Volume=Circle:Area( )*h; /E float GetV( )return Volume; void Show(void) coutx=Circle:xty=Circle:yendl;/F;例10.58 void main (void) Cylinder cy(3,3,2); cy.Show(
28、);coutVolume=cy.GetV()endl;程序执行后输出: x=3 y=3 Volume=25.1327 前往例10.61# include class Circle /定义描画圆的基类,其中(x,y)为圆心,r为半径 protected: float x,y,r; public:Circle(float a,float b,float c) x=a;y=b;r=c;float Area( ) return (r*r*3.14159); /计算圆的面积;class Rectangle /定义描画矩形的基类 protected: float h,w; public: 例10.62 R
29、ectangle(float c, float d) h=c;w=d; float Area(void) /计算矩形面积 return h*w;class Cylinder:public Circle,public Rectangle /描画一个圆柱体的派生类 private: float x,y,z,Volume; /圆柱体的中心坐标与体积 public: Cylinder(float a,float b,float c,float d):Circle(a,b,d),Rectangle(d,d) x=a;y=b;z=c; Volume=Circle:Area( )*h; 例10.63 float GetV( ) return Volume; void Show(void) coutx=xty=y tz=z endl;void main (void) Cylinder cy(3,3,3,2); cy.Show();coutVolume=cy.GetV()endl;程序执行后输出:x=3 y=3 z=3Volume=25.1327 前往例10.71# include cla
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年河北省沧州市中小学编制教师招聘考试备考试题及答案详解
- 2026年梧州市长洲区中小学编制教师招聘考试备考试题及答案详解
- 2026年江西省鹰潭市中小学编制教师招聘考试参考题库及答案详解
- 2026年衡水市桃城区中小学编制教师招聘笔试备考题库及答案详解
- 2026年河南省中小学编制教师招聘笔试备考试题及答案详解
- 2026年上海市静安区中小学编制教师招聘笔试备考试题及答案详解
- 2026年宁夏回族自治区银川市中小学编制教师招聘笔试模拟试题及答案详解
- 2026年清远市清城区中小学编制教师招聘笔试参考题库及答案详解
- 2026年上海市静安区中小学编制教师招聘笔试参考试题及答案详解
- 2026年吐鲁番市高昌区中小学编制教师招聘考试参考题库及答案详解
- 收纳美学培训课件图片
- 简单的日语测试题及答案
- 2025中国中车笔试题库
- DB6505-T 086-2020 双峰驼规模化养殖场建设技术规范
- 交通卡口监控系统维护方案
- 服装管理人员工作职责
- 人教版九年级上册-历史全册课件(课件)【部编教材】
- 中建三局项目目标责任成本测算培训资料
- 心理健康教育国内外研究现状
- 车棚安装服务流程
- 75首古诗英文版
评论
0/150
提交评论