第7章继承与派生1_第1页
第7章继承与派生1_第2页
第7章继承与派生1_第3页
第7章继承与派生1_第4页
第7章继承与派生1_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

本章简介第1章概述7.1类的继承与派生(掌握)7.2访问控制(掌握)7.3类型兼容规则(理解)7.4派生类的构造、析构函数(掌握)7.5派生类的标识与访问(掌握)1继承与派生的目的继承的目的:实现代码重用。派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。类的继承与派生2类的继承与派生的概念保持已有类的特性而构造新类的过程称为继承。在已有类的基础上新增自己的特性而产生新类的过程称为派生。被继承的已有类称为基类(或父类)。派生出的新类称为派生类。类的继承与派生3继承与派生问题举例1类的继承与派生4派生类的声明class派生类名:继承方式基类名{成员声明;};类的继承与派生classStudent

{intnum;

charname[30];

charsex; public: voiddisplay()//对成员函数display的定义 { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl;} };5classStudend1{intnum; //此行原来己有charname[20]; //此行原来己有charsex; //此行原来己有

intage;charaddr[20];public:voiddisplay()//此行原来己有{cout<<"num:"<<num<<endl;//此行原来己有cout<<"name:"<<name<<endl;//此行原来己有cout<<"sex:"<<sex<<endl;//此行原来己有

cout<<"age:"<<age<<endl;cout<<"address:"<<addr<<endl;}};类的继承与派生6利用原来定义的类Student作为基础,再加上新的内容即可,以减少重复的工作量。C++提供的继承机制就是为了解决这个问题的。在C++中,所谓“继承”就是在一个已存在的类的基础上建立一个新的类。已存在的类称为“基类(baseclass)”或“父类(fatherclass)”。新建立的类称为“派生类(derivedclass)”或“子类(sonclass)”。类的继承与派生7classStudent1:publicStudent//声明基类是Student{

intage; //新增加的数据成员stringaddr;//新增加的数据成员public:

voiddisplay_1()//新增加的成员函数{cout<<"age:"<<age<<endl;cout<<"address:"<<addr<<endl;}};类的继承与派生8派生类的构成9继承方式不同继承方式的影响主要体现在:派生类成员对基类成员的访问权限派生类对象对基类成员的访问权限三种继承方式公有继承私有继承保护继承类的继承与派生10公有继承(public)基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象只能访问基类的public成员。类成员的访问控制11公有继承举例类成员的访问控制classBase{public:intb1;protected:intb2;private:intb3;};classD1:publicBase{public:voidtest(){b1=10;//ok,b1为publicb2=20;//ok,b2为protectedb3=30;//error}};12类成员的访问控制voidmain(){D1d1;d1.b1=1;//okd1.b2=2;d1.b3=3;D2d2;d2.b1=4;d2.b2=5;d2.b3=6;D3d3;d3.b1=7;d3.b2=8;d3.b3=9;}13私有继承(private)基类的public和protected成员都以private身份出现在派生类中,基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象不能直接访问基类中的任何成员。类成员的访问控制14私有继承举例classBase{public:intb1;protected:intb2;private:intb3;};classD2:privateBase{public:voidtest(){b1=8;//okb2=9;//ok b3=10;//error}};类成员的访问控制15保护继承(protected)基类的public和protected成员都以protected身份出现在派生类中,基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象不能直接访问基类中的任何成员类成员的访问控制16protected成员的特点与作用对建立其所在类对象的模块来说,它与private成员的性质相同。对于其派生类来说,它与public成员的性质相同。既实现了数据隐藏,又方便继承,实现代码重用。类成员的访问控制17类成员的访问控制classBase{public:intb1;protected:intb2;private:intb3;};

classD3:protectedBase{public:voidtest(){b1=15;//okb2=16;//okb3=17;//error}};18通过继承关系,派生类包含了它的所有基类的成员。派生类对象的数据结构由基类中说明的数据成员和派生类中说明的数据成员共同构成。在创建派生类对象时,派生类对象的初始化,不仅要给派生类中的数据成员初始化,还要给它的基类中的数据成员初始化。如果派生类中还有子对象时,还应包含对子对象初始化。派生类的构造函数和析构函数191、派生类的构造函数

<派生类名>(<总参数表>):<基类构造函数名>(<参数表1>),<子对象名>(<参数表2>){//<派生类中数据成员的初始化>}构造函数的调用顺序如下:

基类构造函数;子类构造函数;派生类构造函数。202、派生类的析构函数执行派生类的析构函数时,也要调用基类及子对象的析构函数。析构顺序如下:先调用派生类的析构函数;子对象的析构函数;基类的析构函数。21#include<iostream.h>classBase{public:Base(){cout<<“\nBasecreated\n”;}};classD_class:publicBase{public:D_class(){cout<<“D_classcreated\n”;}};voidmain(){D_classd;}例如:下面程序显示了构造函数的执行顺序

运行结果:BasecreatedD_classcreated先执行基类的构造函数,再执行派生类的构造函数;执行缺省的析构函数时,先执行派生类,再执行基类。22例如:分析程序的输出结果,分析派生类构造函数及析构函数的特点。#include<iostream.h>classA{public:A(){a=0;}A(inti){a=i;}voidprint(){cout<<a<<“,”;}private:inta;};23classB:publicA{public:B(){b1=b2=0;}//调用基类A的缺省构造函数B(inti){b1=0;b2=i;}//调用A的缺省构造函数B(inti;intj,intk):A(i),b1(j),b2(k){}//调用基类A的带参构造函数voidprint(){A::print();cout<<b1<<“,”<<b2<<endl;}private:intb1,b2;};24voidmain(){Bb1;Bb2(5);Bb3(1,2,3);b1.print();b2.print();b3.print();}0,0,1,0,00,52,3结果:25注意:程序中对象b1,b2,b3调用了不同的三个构造函数实现初始化过程,其内存分配情况如下图所示。000ab1b2A()创建B()创建b1005ab1b2B(inti)创建b2A()创建123ab1b2B(inti,intj,intk)创建b3A(inti)创建可见,创建b1,b2,b3三个对象共调用三次基类A的构造函数,三次派生类B本身的构造函数。析构时也调用了六次析构函数,析构次序与构造次序相反。26例如:下面程序中派生类的数据成员为另一个类的对象,分析输出结果

#include<iostream.h>#include<string.h>classAdvisor{intnoofmeetings;};classStudent{public:Student(char*pname=“noname”){srtcpy(name,pname,);average=semesterhours=0;}27voidaddcourse(inthours,floatgrade){average=semesterhours*average+grade;//总分semesterhours+=hours;//总修学时数average/=semesterhours;//平均分}intgethours(){returnsemesterhours;}floatgetaverage(){returnaverage;}28

voiddisplay(){cout<<“name=”<<name<<“,hours=”<<semesterhours<<“,average=”<<average<<endl;}protected:charname[40];intsemesterhours;floataverage;};classGraduatestudent:publicStudent{public:getqulifier(){returnqualifiergrade;}29

protected:Advisoradvisor;//类对象成员intqualifiergrade;};voidmain(){Studentds(“Wangmingundergrade”);Graduatestudentgs;ds.addcourse(3,2.5);ds.display();gs.addcourse(3,3.0);//派生类对象访问公共成员函数gs.display();}30结果:name=Wangmingundergrade,hours=3,average=0.8333333name=noname,hours=3,average=1派生类对象gs的创建初始化过程如图所示:……name[40]semesterhoursaveragenoofmetingsqualifergradegs对象的内存空间调用基类构造函数初始化调用Advisor类构造函数初始化调用Graduatestudent派生类本身的构造函数初始化31类型兼容规则一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:派生类的对象可以被赋值给基类对象。派生类的对象可以初始化基类的引用。派生类对象的地址可以赋给指向基类的指针。通过基类对象名、指针只能使用从基类继承的成员类型兼容32单一继承时的构造函数派生类名::派生类名(基类所需的形参,本类成员所需的形参):基类名(参数表){本类成员初始化赋值语句;};派生类的构造、析构函数继承时的构造函数总结33继承时的构造函数总结基类的构造函数不被继承,派生类中需要声明自己的构造函数。声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类

温馨提示

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

评论

0/150

提交评论