c++课件第十一章继承与派生_第1页
c++课件第十一章继承与派生_第2页
c++课件第十一章继承与派生_第3页
c++课件第十一章继承与派生_第4页
c++课件第十一章继承与派生_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

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

文档简介

1、.第11章 继承和派生11.1继承与派生的概念 图11.1 图11.2本书中的约定,箭头表示继承的方向,从派生类指向基类。图11.3图11.4图11.511.2派生类的声明方式class Studentpublic:void get_valuecin>>num>>name>>sex;void display cout<<"num: "<<num<<endl;cout<<"name: "<<name<<endl;cout<<"s

2、ex: "<<sex<<endl;private :int num;string name;char sex; class Student1: public Studentpublic:void get_value_1cin>>age>>addr;void display_1cout<<"age:"<<age<<endl; cout<<"address: "<<addr<<endl;private: int age; stri

3、ng addr;继承方式有:public公有,private私有,protected保护11.3派生类的构成 图11.611.4派生类成员的访问属性11.4.1公用继承 例11.1公有继承实例。#include <iostream>#include <string>using namespace std;class Studentpublic:void get_valuecin>>num>>name>>sex;void display cout<<"num: "<<num<<en

4、dl;cout<<"name: "<<name<<endl;cout<<"sex: "<<sex<<endl;protected :int num;string name;char sex; class Student1: public Studentpublic:void get_value_1cin>>age>>addr;void display_1 /cout<<"num: "<<num<<endl

5、; /企图引用基类的私有成员,错误 /cout<<"name: "<<name<<endl; /企图引用基类的私有成员,错误 /cout<<"sex: "<<sex<<endl; /企图引用基类的私有成员,错误 cout<<"age: "<<age<<endl; /引用派生类的私有成员,正确 cout<<"address: "<<addr<<endl; /引用派生类的私有成

6、员,正确private: int age; string addr;int mainStudent1 stud1;stud1.get_value;stud1.get_value_1;stud1.display;stud1.display_1;return 0;1001 huang F 18 Beijingnum: 1001name: huangsex: Fage: 18address: Beijing#include<iostream.h>class Locationprivate: int X,Y;public:int GetXreturn X;int GetYreturn Y;

7、int Z;protected:int P;class Rectangle:public Locationprivate: int Height,Width;public:/int GetHHX=5;return Height;/在公有派生中基类的私有成员在派生类中是不可访问的 int GetHcout<<GetX<<endl;Z=88;return Height;/在公有派生中基类的公有成员在派生类中还是公有成员int GetWP=55;return Width;/在公有派生中基类的保护成员在派生类中还是保护成员;class test:public Rectangle

8、void fun2P=89;/P在test类中是可访问的void fun1Z=66;/Z在test类中是可访问的;void funRectangle r; /定义对象rint Xvalue=r.GetX; /使用基类返回r的X值int h=r.GetH; /通过派生类返回r的H值r.Z=99; /在公有派生中基类的公有成员在/派生类中还是公有成员 r.P=109;/在公有派生中基类的保护成员/在派生类中还是保护成员void mainfun;11.4.2私有继承 图11.7例11.2 私有继承实例#include <iostream>#include <string>us

9、ing namespace std;#include <iostream>#include <string>using namespace std;class Studentpublic:void display cout<<"num: "<<num<<endl;cout<<"name: "<<name<<endl;cout<<"sex: "<<sex<<endl;private :int num;str

10、ing name;char sex; class Student1: private Studentpublic:void display_1 display;/调用基类公有成员函数,/在派生类中成为私有成员cout<<"age: "<<age<<endl;/引用派生类的私有成员,正确 cout<<"address: "<<addr<<endl;/引用派生类的私有成员,正确private:int age; string addr; ;int mainStudent1 stud1;/s

11、tud1.display;/错误stud1.display_1;return 0;#include<iostream.h>class Locationprivate: int X,Y;public:int GetXreturn X;int GetYreturn Y;int Z;protected:int P;class Rectangle:private Locationprivate: int Height,Width;public:/int GetHHX=5;return Height;/在私有派生中基类的私有成员在派生类中是不可访问的int GetHcout<<G

12、etX<<endl;Z=88;return Height;/在私有派生中基类的公有成员在派生类中是私有成员int GetWP=55;return Width;/在私有派生中基类的保护成员在派生类中是私有成员;class test:public Rectangle/void fun2P=89;/P在test类中是不可访问的/void fun1Z=66;/Z在test类中是不可访问的;void funRectangle r; /定义对象r/int Xvalue=r.GetX; /使用基类返回r的X值int h=r.GetH; /通过派生类返回r的H值 /r.Z=99;/在私有派生中基类

13、的公有成员在派生类中是私有成员/r.P=109;/在私有派生中基类的保护成员在派生类中还是私有成员void mainfun;11.4.3保护成员和保护继承例11.3在派生类中引用保护成员。#include <iostream>#include <string>using namespace std;class Student /声明基类public: /基类公用成员 void display ;protected : /基类保护成员 int num; string name; char sex;void Student:display cout<<"

14、;num: "<<num<<endl; cout<<"name: "<<name<<endl; cout<<"sex: "<<sex<<endl;class Student1: protected Student /用protected继承方式声明一个派生类public:void display1 ;private:int age; string addr;void Student1:display1 cout<<"num: &

15、quot;<<num<<endl; /引用基类的保护成员,合法 cout<<"name: "<<name<<endl;/引用基类的保护成员,合法 cout<<"sex: "<<sex<<endl;/引用基类的保护成员,合法 cout<<"age: "<<age<<endl;/引用派生类的私有成员,合法 cout<<"address: "<<addr<<

16、;endl;/引用派生类的私有成员,合法int main Student1 stud1; /stud1是派生类student2的对象stud1.display1 ;/display是派生类中的保护成员函数return 0;#include<iostream.h>class Locationprivate: int X,Y;public:int GetXreturn X;int GetYreturn Y;int Z;protected:int P;class Rectangle:protected Locationprivate: int Height,Width;public:/i

17、nt GetHHX=5;return Height;/在保护派生中基类的私有成员在派生类中是不可访问的int GetHcout<<GetX<<endl;Z=88;return Height;/在保护派生中基类的公有成员在派生类中是保护的int GetWP=55;return Width;/在保护派生中基类的保护成员在派生类中是保护的;class test:public Rectanglevoid fun2P=89;void fun1Z=66;class test_test:public testvoid fun3P=89;/证明P是保护的void fun4Z=66;/证

18、明Z是保护的;void funRectangle r; /定义对象rint h=r.GetH; /通过派生类返回r的H值 /r.Z=99;/在保护派生中基类的公有成员在派生类中是保护的 /r.P=109;/在保护派生中基类的公有成员在派生类中是保护的void mainfun;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 /p

19、ublic方式public:void f3 ;protected:void f4;private:int m;class C: protected B /protected方式public:void f5;private:int n; i f2 j k基类A派生类B派生类C11.5派生类的构造函数和析构函数11.5.1简单的派生类的构造函数例11.5 简单的派生类的构造函数#include <iostream>#include<string>using namespace std;class Student /声明基类public: /公用部分 Studentint n

20、,string nam,char s /基类构造函数 num=n; name=nam; sex=s; Student /基类析构函数protected: /保护部分 int num; string name; char sex ; ;class Student1: public Student/声明公用派生类studentpublic: Student1int n,string nam,char s,int a,char ad : Studentn,nam,s/派生类构造函数 age=a;/在函数体中只对派生类新增的数据成员初始化 addr=ad; void show cout<<

21、"num: "<<num<<endl; cout<<"name: "<<name<<endl; cout<<"sex: "<<sex<<endl; cout<<"age: "<<age<<endl; cout<<"address: "<<addr<<endl<<endl; Student1 /派生类析构函数privat

22、e: /派生类的私有部分 int age; string addr; ; int main Student1 stud110010,"Wang-li",'f',19,"115 Beijing Road,Shanghai"Student1 stud210011,"Zhang-fun",'m',21,"213 Shanghai Road,Beijing"stud1.show ; /输出第一个学生的数据stud2.show ; /输出第二个学生的数据return 0;num: 10010n

23、ame: Wang-lisex: fage: 19address: 115 Beijing Road,Shanghainum: 10011name: Zhang-funsex: mage: 21address: 213 Shanghai Road,Beijing图11.10图11.1111.5.2有子对象的派生类的构造函数例11.6包含子对象的派生类的构造函数。#include <iostream>#include <string>using namespace std;class Student /声明基类public: /公用部分Studentint n,strin

24、g nam/基类构造函数 num=n;name=nam;void display /输出基类数据成员 cout<<"num:"<<num<<endl<<"name:"<<name<<endl;protected: /保护部分 int num; string name;class Student1: public Student /用public继承方式声明派生类studentpublic:Student1int n,string nam,int n1,string nam1,int

25、a,string ad:Studentn,nam,monitorn1,nam1 /派生类构造函数 age=a; /在此处只对派生类新增的数据成员初始化 addr=ad; void show cout<<"This student is:"<<endl;display; /输出num和namecout<<"age: "<<age<<endl;cout<<"address: "<<addr<<endl<<endl; void sho

26、w_monitor/输出子对象的数据成员 cout<<endl<<"Class monitor is:"<<endl;monitor.display;/调用基类成员函数 private: /派生类的私有数据 Student monitor; /定义子对象班长 int age; string addr; ; int main Student1 stud110010,"Wang-li",10001,"Li-sun",19,"115 Beijing Road,Shanghai"stud

27、1.show ;/输出第一个学生的数据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

28、 <iostream>#include<string>using namespace std;class Student /声明基类public: /公用部分 Studentint n, string nam/基类构造函数 num=n;name=nam; void display /输出基类数据成员 cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl; protected: /保护部分 int num; /基类有

29、两个数据成员 string name;class Student1: public Student/声明公用派生类Student1 public: Student1int n,string nam,int a:Studentn,nam/派生类构造函数 age=a; /在此处只对派生类新增的数据成员初始化 void show /输出num,name和age display; /输出num和namecout<<"age: "<<age<<endl; private: /派生类的私有数据 int age; /增加一个数据成员;class Stu

30、dent2:public Student1 /声明间接公用派生类student2 public: /下面是间接派生类构造函数 Student2int n,string nam,int a,int s:Student1n,nam,a score=s; void show_all /输出全部数据成员 show; /输出num和name cout<<"score:"<<score<<endl;/输出age private: int score;/增加一个数据成员; int main Student2 stud10010,"Li&quo

31、t;,17,89;stud.show_all ; /输出学生的全部数据return 0;num:10010name:Liage: 17score:89图11.1311.5.4派生类构造函数的特殊形式11.5.5派生类的析构函数析构函数的执行顺序与构造函数正好相反:先执行派生类的析构函数,再执行子对象的析构函数,最后执行基类的析构函数。/测试例子#include<iostream.h>class base private: int a;public: baseint i; base; base : baseint ia=i;cout<< "constructin

32、g base "<<a<<endl;base : basecout<< "destroying base "<<a<<endl;class derived : public base private: int d; base member;public: derivedint i,int j,int k; derived;derived : derivedint i,int j,int k:basei,memberjd=k;cout<< "constructing derived&q

33、uot;<<endl;derived : derivedcout<< "destroying derived"<<endl;void mainderived d5,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新增加的成员11.6.2

34、多重继承派生类的构造函数派生类构造函数总参数表列:基类1构造函数名参数表列,基类2构造函数参数表列,基类3构造函数参数表列派生类中新增数据成员初始化语句例11.8 声明一个老师Teacher类和一个学生Student类,用多重继承方式声明一个研究生Graduate派生类。老师类包括数据成员name,age,title.学生类中包括数据成员name1,sex,score.在定义派生类对象时给出初始化数据,然后输出这些数据。#include <iostream>#include <string>using namespace std;class Teacher /声明Tea

35、cher老师类public: /公用部分Teacherstring nam,int a,string t name=nam;age=a;title=t;/构造函数 void display/输出老师有关数据 cout<<"name:"<<name<<endl;cout<<"age"<<age<<endl;cout<<"title:"<<title<<endl; protected: /保护部分 string name; int

36、age; string title; /职称;class Student /声明类Student学生public:Studentstring nam,char s,float sco name1=nam;sex=s;score=sco;/构造函数void display1 /输出学生有关数据 cout<<"name:"<<name1<<endl;cout<<"sex:"<<sex<<endl;cout<<"score:"<<score<

37、;<endl; protected: /保护部分string name1;char sex;float score; /成绩;class Graduate:public Teacher,public Student public:/声明多重继承的派生类GraduateGraduatestring nam,int a,char s,string t,float sco,float w: Teachernam,a,t,Studentnam,s,sco,wagewvoid show /输出人员的有关数据 cout<<"name:"<<name<

38、<endl;cout<<"age:"<<age<<endl;cout<<"sex:"<<sex<<endl;cout<<"score:"<<score<<endl;cout<<"title:"<<title<<endl;cout<<"wages:"<<wage<<endl; private: float wage

39、; /工资;int main Graduate grad1"Wang-li",24,'f',"assistant", 89.5,1234.5;grad1.show ;return 0;name:Wang-liage:24sex:fscore:89.5title:assistantwages:1234.5#include<iostream.h>class base1public:base1cout<< "constructing basel"<<endl;class base2publ

40、ic:base2cout<< "constructing base2"<<endl;class base3public:base3cout<<"constructing base3"<<endl;class base4public:base4cout<<"constructing base4"<<endl;class derived : public base2,public base1,public base3private:base4 memobj;void

41、mainderived 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;产生二义性,应改为 c1.A:a=3;使用基类名来限定c1.display;产生二义性,应改为c1.

42、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是从同一个基类派生的。class Npublic:int a;void displaycout<<&qu

43、ot;A:a="<<a<<endl;class A:public Npublic:int a1:class B:public Npublic:int a2:class C:public A,public Bpublic:int a3:void showcout<<"a3="<<a3<<endl;void mainC c1; 图11.19 图11. 20怎样才能访问类A中从基类N继承下来的成员呢?不能写成c1.a=3;c1.dispay;或c1.N:a=3;c1.N:display;应该写成:c1.A:a=

44、3;c1.B: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 AAint i.;class B:virtual public ABint n:An.;class C:virtual public A

45、Cint n:An.;class D:public B,public CDint n:An,Bn,Cn.;注意:在定义类D的构造函数时,与以往使用的方法有所不同。以前,在派生类的构造函数中只负责对其直接基类的初始化,再由其直接基类负责对间接基类初始化。如今,由于虚基类在派生类中只有一份数据成员,所以这份数据成员的初始化,必须由派生类直接给出。3. 虚基类的简单应用举例 图11.25例11.9 在例11.8的根底上,在Teacher类和Student类之上增加一个共同的基类Person,作为人员的一些根本数据都放在Person中,在Teacher类和Student类中增加一些必要数据。#incl

46、ude <iostream>#include <string>using namespace std;/定义公共基类Personclass Person public:Personchar *nam,char s,int a /构造函数 strcpyname,nam;sex=s;age=a;protected: /保护成员char name20;char sex;int age;/定义类Teacherclass Teacher:virtual public Personpublic: /声明Person为公用继承的虚基类 Teacherchar *nam,char s,

47、int a, char *t:Personnam,s,a strcpytitle,t; /构造函数protected: /保护成员 char title10;/职称;/定义类Studentclass Student:virtual public Person public: /声明Person为公用继承的虚基类Studentchar *nam,char s,int a,float sco: Personnam,s,a,scoresco/构造函数初始化表protected: /保护成员 float score; /成绩;/定义多重继承的派生类Graduateclass Graduate:publ

48、ic Teacher,public Studentpublic:/声明Teacher和Student类为公用继承的直接基类Graduatechar *nam,char s,int a,char *t, float sco,float w: /构造函数 Personnam,s,a,Teachernam,s,a,t, Studentnam,s,a,sco,wagew /初始化表 void show /输出研究生的有关数据 cout<<"name:"<<name<<endl;cout<<"age:"<<

49、;age<<endl;cout<<"sex:"<<sex<<endl;cout<<"score:"<<score<<endl;cout<<"title:"<<title<<endl;cout<<"wages:"<<wage<<endl; private: float wage; /工资;int main Graduate grad1"Wang-li&q

50、uot;,'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赋值但是,反过来不成立,基类对象不能向派生类对象赋值,因为基类不包含派生类新增数据成员。图11.262派生类对象可以替代基类对象向基类对象的

51、引用进展赋值或初始化。A a1;/定义基类A的对象a1B b1;/定义类A的公用派生类B的对象b1A&r=b1;/定义基类A对象的引用变量r,并用 /派生类B的对象b1对其进展初始化注意:此时r并不是b1的别名,也不与b1共享同一段存储单元。它只是b1中基类部分的别名,r与b1中基类部分共享同一段存储单元,r与b1具有一样的起始地址。3假设函数的参数是基类对象或基类对象的引用,相应的实参可以用派生类的对象。void funA& rcout<<r.num<<endl;funb1;4派生类对象的地址可以赋值指向基类对象的指针变量。例11.10 定义一个基类S

52、tudent学生,再定义Student类的公用派生类Graduate研究生,用指向基类的对象的指针输出数据。#include <iostream>#include <string>using namespace std;class Studentpublic: Studentint,string,float; void display;private: int num; string name; float score;Student:Studentint n,string nam,float snum=n;name=nam;score=s;void Student:d

53、isplaycout<<endl<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"score:"<<score<<endl;class Graduate:public Studentpublic:Graduateint,string,float,float;void display;private:float pay;void Graduate:displayStudent:display;cout<<"pay="<<pay<<endl;Graduate:Graduateint n,string nam,float s,float p:Studentn,nam,s,paypint mainStudent stud11001,"Li",87.5;Graduate grad12001,"Wang",98.5,563.5;Studen

温馨提示

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

评论

0/150

提交评论