




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第11章 继承和派生11.1继承与派生的概念 图11.1 图11.2本书中的约定,箭头表示继承的方向,从派生类指向基类。图11.3图11.4图11.511.2派生类的声明方式class Studentpublic:void get_value()cinnumnamesex;void display( )coutnum: numendl;coutname: nameendl;coutsex: sexageaddr;void display_1()coutage:ageendl; coutaddress: addrendl;private: int age; string addr;继承方式有:p
2、ublic(公有),private(私有),protected(保护)11.3派生类的构成 图11.611.4派生类成员的访问属性11.4.1公用继承 例11.1公有继承实例。#include #include using namespace std;class Studentpublic:void get_value()cinnumnamesex;void display( )coutnum: numendl;coutname: nameendl;coutsex: sexageaddr;void display_1() /coutnum: numendl; /企图引用基类的私有成员,错误 /
3、coutname: nameendl; /企图引用基类的私有成员,错误 /coutsex: sexendl; /企图引用基类的私有成员,错误 coutage: ageendl; /引用派生类的私有成员,正确 coutaddress: addrendl; /引用派生类的私有成员,正确private: int age; string addr;int main()Student1 stud1;stud1.get_value();stud1.get_value_1();stud1.display();stud1.display_1();return 0;1001 huang F 18 Beijing
4、num: 1001name: huangsex: Fage: 18address: Beijing#includeclass Locationprivate: int X,Y;public:int GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:public Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在公有派生中基类的私有成员在派生类中是不可访问的 int GetH()coutGetX()endl;
5、Z=88;return Height;/在公有派生中基类的公有成员在派生类中还是公有成员int GetW()P=55;return Width;/在公有派生中基类的保护成员在派生类中还是保护成员;class test:public Rectanglevoid fun2()P=89;/P在test类中是可访问的void fun1()Z=66;/Z在test类中是可访问的;void fun()Rectangle r; /定义对象rint Xvalue=r.GetX(); /使用基类返回r的X值int h=r.GetH(); /通过派生类返回r的H值r.Z=99; /在公有派生中基类的公有成员在/派
6、生类中还是公有成员 r.P=109;/在公有派生中基类的保护成员/在派生类中还是保护成员void main()fun();11.4.2私有继承 图11.7例11.2 私有继承实例#include #include using namespace std;#include #include using namespace std;class Studentpublic:void display( ) coutnum: numendl;coutname: nameendl;coutsex: sexendl;private :int num;string name;char sex; class S
7、tudent1: private Studentpublic:void display_1() display();/调用基类公有成员函数,/在派生类中成为私有成员coutage: ageendl;/引用派生类的私有成员,正确 coutaddress: addrendl;/引用派生类的私有成员,正确private:int age; string addr; ;int main()Student1 stud1;/stud1.display();/错误stud1.display_1();return 0;#includeclass Locationprivate: int X,Y;public:i
8、nt GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:private Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在私有派生中基类的私有成员在派生类中是不可访问的int GetH()coutGetX()endl;Z=88;return Height;/在私有派生中基类的公有成员在派生类中是私有成员int GetW()P=55;return Width;/在私有派生中基类的保护成员在派生类中是私有成员;
9、class test:public Rectangle/void fun2()P=89;/P在test类中是不可访问的/void fun1()Z=66;/Z在test类中是不可访问的;void fun()Rectangle r; /定义对象r/int Xvalue=r.GetX(); /使用基类返回r的X值int h=r.GetH(); /通过派生类返回r的H值 /r.Z=99;/在私有派生中基类的公有成员在派生类中是私有成员/r.P=109;/在私有派生中基类的保护成员在派生类中还是私有成员void main()fun();11.4.3保护成员和保护继承例11.3在派生类中引用保护成员。#i
10、nclude #include using namespace std;class Student /声明基类public: /基类公用成员 void display( );protected : /基类保护成员 int num; string name; char sex;void Student:display( )coutnum: numendl; coutname: nameendl; coutsex: sexendl;class Student1: protected Student /用protected继承方式声明一个派生类public:void display1( );priv
11、ate:int age; string addr;void Student1:display1( )coutnum: numendl; /引用基类的保护成员,合法 coutname: nameendl;/引用基类的保护成员,合法 coutsex: sexendl;/引用基类的保护成员,合法 coutage: ageendl;/引用派生类的私有成员,合法 coutaddress: addrendl;/引用派生类的私有成员,合法int main( )Student1 stud1; /stud1是派生类student2的对象stud1.display1( );/display是派生类中的保护成员函数
12、return 0;#includeclass Locationprivate: int X,Y;public:int GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:protected Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在保护派生中基类的私有成员在派生类中是不可访问的int GetH()coutGetX()endl;Z=88;return Height;/在保护派生中基类的公有成员在派生类中
13、是保护的int GetW()P=55;return Width;/在保护派生中基类的保护成员在派生类中是保护的;class test:public Rectanglevoid fun2()P=89;void fun1()Z=66;class test_test:public testvoid fun3()P=89;/证明P是保护的void fun4()Z=66;/证明Z是保护的;void fun()Rectangle r; /定义对象rint h=r.GetH(); /通过派生类返回r的H值 /r.Z=99;/在保护派生中基类的公有成员在派生类中是保护的 /r.P=109;/在保护派生中基类的
14、公有成员在派生类中是保护的void main()fun();test t1;/t1.P=90;/错误证明P不是公有的/t1.Z=79;/错误证明Z不是公有的11.4.4多级派生时的访问属性例11.4 多级派生时的访问属性class A /基类public:int i;protected:void f2();int j;private:int k;class B: public A /public方式public:void f3( );protected:void f4();private:int m;class C: protected B /protected方式public:void f5
15、();private:int n; i f2 j k基类A派生类B派生类C11.5派生类的构造函数和析构函数11.5.1简单的派生类的构造函数例11.5 简单的派生类的构造函数#include #includeusing namespace std;class Student /声明基类public: /公用部分 Student(int n,string nam,char s )/基类构造函数 num=n; name=nam; sex=s; Student( ) /基类析构函数protected: /保护部分 int num; string name; char sex ; ;class St
16、udent1: public Student/声明公用派生类studentpublic: Student1(int n,string nam,char s,int a,char ad) : Student(n,nam,s)/派生类构造函数 age=a;/在函数体中只对派生类新增的数据成员初始化 addr=ad; void show( ) coutnum: numendl; coutname: nameendl; coutsex: sexendl; coutage: ageendl; coutaddress: addrendlendl; Student1( ) /派生类析构函数private:
17、/派生类的私有部分 int age; string addr; ; int main( )Student1 stud1(10010,Wang-li,f,19,115 Beijing Road,Shanghai);Student1 stud2(10011,Zhang-fun,m,21,213 Shanghai Road,Beijing);stud1.show( ); /输出第一个学生的数据stud2.show( ); /输出第二个学生的数据return 0;num: 10010name: Wang-lisex: fage: 19address: 115 Beijing Road,Shanghai
18、num: 10011name: Zhang-funsex: mage: 21address: 213 Shanghai Road,Beijing图11.10图11.1111.5.2有子对象的派生类的构造函数例11.6包含子对象的派生类的构造函数。#include #include using namespace std;class Student /声明基类public: /公用部分Student(int n,string nam)/基类构造函数 num=n;name=nam;void display() /输出基类数据成员 coutnum:numendlname:nameendl;prote
19、cted: /保护部分 int num; string name;class Student1: public Student /用public继承方式声明派生类studentpublic:Student1(int n,string nam,int n1,string nam1,int a,string ad):Student(n,nam),monitor(n1,nam1) /派生类构造函数 age=a; /在此处只对派生类新增的数据成员初始化 addr=ad; void show( ) coutThis student is:endl;display(); /输出num和namecoutag
20、e: ageendl;coutaddress: addrendlendl; void show_monitor()/输出子对象的数据成员 coutendlClass monitor is:endl;monitor.display();/调用基类成员函数 private: /派生类的私有数据 Student monitor; /定义子对象(班长) int age; string addr; ; int main( )Student1 stud1(10010,Wang-li,10001,Li-sun,19,115 Beijing Road,Shanghai);stud1.show( );/输出第一
21、个学生的数据stud1.show_monitor(); /输出子对象的数据return 0;This student is:num:10010name:Wang-liage: 19address: 115 Beijing Road,ShanghaiClass monitor is:num:10001name:Li-sun 图11.12执行派生类构造函数的顺序是:(1) 调用基类构造函数,对基类数据成员初始化。(2) 调用子对象的构造函数,对子对象的数据成员初始化。(3) 执行派生类构造函数,对派生类数据成员初始化。11.5.3多层派生时的构造函数例11.7#include #includeus
22、ing namespace std;class Student /声明基类public: /公用部分 Student(int n, string nam)/基类构造函数 num=n;name=nam; void display() /输出基类数据成员 coutnum:numendl;coutname:nameendl; protected: /保护部分 int num; /基类有两个数据成员 string name;class Student1: public Student/声明公用派生类Student1 public: Student1(int n,string nam,int a):St
23、udent(n,nam)/派生类构造函数 age=a; /在此处只对派生类新增的数据成员初始化 void show( ) /输出num,name和age display(); /输出num和namecoutage: ageendl; private: /派生类的私有数据 int age; /增加一个数据成员;class Student2:public Student1 /声明间接公用派生类student2 public: /下面是间接派生类构造函数 Student2(int n,string nam,int a,int s):Student1(n,nam,a) score=s; void sh
24、ow_all() /输出全部数据成员 show(); /输出num和name coutscore:scoreendl;/输出age private: int score;/增加一个数据成员; int main( )Student2 stud(10010,Li,17,89);stud.show_all( ); /输出学生的全部数据return 0;num:10010name:Liage: 17score:89图11.1311.5.4派生类构造函数的特殊形式11.5.5派生类的析构函数析构函数的执行顺序与构造函数正好相反:先执行派生类的析构函数,再执行子对象的析构函数,最后执行基类的析构函数。/测
25、试例子#includeclass base private: int a;public: base(int i); base(); base : base(int i)a=i;cout constructing base aendl;base : base()cout destroying base aendl;class derived : public base private: int d; base member;public: derived(int i,int j,int k); derived();derived : derived(int i,int j,int k):base
26、(i),member(j)d=k;cout constructing derivedendl;derived : derived()cout destroying derivedendl;void main()derived d(5,8,12);constructing base 5constructing base 8constructing deriveddestroying deriveddestroying base 8destroying base 511.6多重继承11.6.1声明多重继承的方法class D:public A,private B,protected C类D新增加的
27、成员11.6.2多重继承派生类的构造函数派生类构造函数(总参数表列):基类1构造函数名(参数表列),基类2构造函数(参数表列),基类3构造函数(参数表列)派生类中新增数据成员初始化语句例11.8 声明一个教师(Teacher)类和一个学生(Student)类,用多重继承方式声明一个研究生(Graduate)派生类。教师类包括数据成员name,age,title.学生类中包括数据成员name1,sex,score.在定义派生类对象时给出初始化数据,然后输出这些数据。#include #include using namespace std;class Teacher /声明Teacher(教师)
28、类public: /公用部分Teacher(string nam,int a,string t) name=nam;age=a;title=t;/构造函数 void display()/输出教师有关数据 coutname:nameendl;coutageageendl;couttitle:titleendl; protected: /保护部分 string name; int age; string title; /职称;class Student /声明类Student(学生)public:Student(string nam,char s,float sco) name1=nam;sex=
29、s;score=sco;/构造函数void display1() /输出学生有关数据 coutname:name1endl;coutsex:sexendl;coutscore:scoreendl; protected: /保护部分string name1;char sex;float score; /成绩;class Graduate:public Teacher,public Student public:/声明多重继承的派生类GraduateGraduate(string nam,int a,char s,string t,float sco,float w): Teacher(nam,a
30、,t),Student(nam,s,sco),wage(w)void show( ) /输出人员的有关数据 coutname:nameendl;coutage:ageendl;coutsex:sexendl;coutscore:scoreendl;couttitle:titleendl;coutwages:wageendl; private: float wage; /工资;int main( )Graduate grad1(Wang-li,24,f,assistant, 89.5,1234.5);grad1.show( );return 0;name:Wang-liage:24sex:fsc
31、ore:89.5title:assistantwages:1234.5#includeclass base1public:base1()cout constructing baselendl;class base2public:base2()cout constructing base2endl;class base3public:base3()coutconstructing base3endl;class base4public:base4()coutconstructing base4endl;class derived : public base2,public base1,publi
32、c base3private:base4 memobj;void main()derived d;constructing base2constructing baselconstructing base3constructing base411.6.3多重继承引起的二义性问题(1) 两个基类有同名成员。class Apublic:int a:void display();class Bpublic:int a:void display();class C:public A,public Bpublic:int b:void show();图11.14C c1;c1.a=3;产生二义性,应改为
33、 c1.A:a=3;使用基类名来限定c1.display();产生二义性,应改为c1.B:display();在C类成员函数中可以这么写:A:a=3;B:a=8; B:display();图11.15(2) 两个基类和派生类都有同名成员,将上面C类改为:class C:public A,public Bpublic:int a;void display();C c1;c1.a=3;/正确,派生类同名成员覆盖了基类中同名成员。c1.display();/正确。此时强制使用基类名的办法是;c1.A:a=3;/使用基类名来限定c1.B:display();/使用基类名来限定(3)如果类A和类B是从同
34、一个基类派生的。class Npublic:int a;void display()coutA:a=aendl;class A:public Npublic:int a1:class B:public Npublic:int a2:class C:public A,public Bpublic:int a3:void show()couta3=a3endl;void main()C c1; 图11.19 图11. 20怎样才能访问类A中从基类N继承下来的成员呢?不能写成c1.a=3;c1.dispay();或c1.N:a=3;c1.N:display();应该写成:c1.A:a=3;c1.B:
35、display();11.6.4虚基类1. 虚基类的作用 图11.21图11.22现将类A声明为虚基类:class A.;class B:virtual public A.;class C:virtual public A.;class D:public B,public C.;则此时,D只继承基类A一次。 图11.24图11.23注意:为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。2. 虚基类的初始化class AA(int i).;class B:virtual public AB(int n):A(n).;class C:virtual public A
36、C(int n):A(n).;class D:public B,public CD(int n):A(n),B(n),C(n).;注意:在定义类D的构造函数时,与以往使用的方法有所不同。以前,在派生类的构造函数中只负责对其直接基类的初始化,再由其直接基类负责对间接基类初始化。现在,由于虚基类在派生类中只有一份数据成员,所以这份数据成员的初始化,必须由派生类直接给出。3. 虚基类的简单应用举例 图11.25例11.9 在例11.8的基础上,在Teacher类和Student类之上增加一个共同的基类Person,作为人员的一些基本数据都放在Person中,在Teacher类和Student类中增加
37、一些必要数据。#include #include using namespace std;/定义公共基类Personclass Person public:Person(char *nam,char s,int a) /构造函数 strcpy(name,nam);sex=s;age=a;protected: /保护成员char name20;char sex;int age;/定义类Teacherclass Teacher:virtual public Personpublic: /声明Person为公用继承的虚基类 Teacher(char *nam,char s,int a, char *
38、t):Person(nam,s,a) strcpy(title,t); /构造函数protected: /保护成员 char title10;/职称;/定义类Studentclass Student:virtual public Person public: /声明Person为公用继承的虚基类Student(char *nam,char s,int a,float sco): Person(nam,s,a),score(sco)/构造函数初始化表protected: /保护成员 float score; /成绩;/定义多重继承的派生类Graduateclass Graduate:public
39、 Teacher,public Studentpublic:/声明Teacher和Student类为公用继承的直接基类Graduate(char *nam,char s,int a,char *t, float sco,float w): /构造函数 Person(nam,s,a),Teacher(nam,s,a,t), Student(nam,s,a,sco),wage(w) /初始化表 void show( ) /输出研究生的有关数据 coutname:nameendl;coutage:ageendl;coutsex:sexendl;coutscore:scoreendl;couttitl
40、e:titleendl;coutwages:wageendl; private: float wage; /工资;int main( )Graduate grad1(Wang-li,f, 24,assistant,89.5,1234.5);grad1.show( );return 0;name:Wang-liage:24sex:fscore:89.5title:assistantwages:1234.511.7基类与派生类的转换(1) 派生类对象可以向基类对象赋值。A a1;/定义基类A的对象a1B b1;/定义类A的公用派生类B的对象b1a1=b1;/用派生类B的对象b1对基类对象a1赋值但
41、是,反过来不成立,基类对象不能向派生类对象赋值,因为基类不包含派生类新增数据成员。图11.26(2)派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化。A a1;/定义基类A的对象a1B b1;/定义类A的公用派生类B的对象b1A&r=b1;/定义基类A对象的引用变量r,并用 /派生类B的对象b1对其进行初始化注意:此时r并不是b1的别名,也不与b1共享同一段存储单元。它只是b1中基类部分的别名,r与b1中基类部分共享同一段存储单元,r与b1具有相同的起始地址。(3)如果函数的参数是基类对象或基类对象的引用,相应的实参可以用派生类的对象。void fun(A& r)coutr.nume
42、ndl;fun(b1);(4)派生类对象的地址可以赋值指向基类对象的指针变量。例11.10 定义一个基类Student(学生),再定义Student类的公用派生类Graduate(研究生),用指向基类的对象的指针输出数据。#include #include using namespace std;class Studentpublic: Student(int,string,float); void display();private: int num; string name; float score;Student:Student(int n,string nam,float s)num=n;name=nam;score=s;void Student:display()coutendlnum:numendl;coutname:nameendl;coutscore:scoreendl;class Graduate:publi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年速冻丸类制品合作协议书
- 智慧城市发展背景下智能交通系统的战略规划
- 2025年紫外固化材料项目发展计划
- 创新教育心理学方法激发学生内在动力
- 情绪心理学与课堂氛围的营造
- 医疗培训中的教育政策与效果评估研究
- 以数据为支撑的学生行为心理分析实践
- 在线教育在商业领域的广泛应用及未来前景
- 混合式学习模式在医学教学中的实践应用研究
- 中职教育课件
- 康复科护理中的疼痛管理
- 医疗机构卫生法律制度与监督-
- 液压动力系统中英文对照外文翻译文献
- 已有设施管线的加固和保护等特殊情况下的施工措施
- 商品混凝土技术规格书
- 决策力与执行力
- 加压法制备硫酸铝新技术
- 第7课日本の秋は涼しいです课件高中日语华东理工版新编日语教程1
- 发酵车间标准操作规程、规范及管理办法(SOP)
- 2022年FIBA篮球竞赛规则
- 武汉铁路职业技术学院教师招聘考试历年真题
评论
0/150
提交评论