chapter05 类的继承和派生
C++第5章习题参考答案
1.什么是类的继承与派生?继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上的代码重用。
继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。
它使得某类对象可以继承另外一类对象的特征和能力。
继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。
通过继承方式定义的子类也称为派生类。
2.类的三种继承方式之间的区别是什么?类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。
对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。
表5.1列出了不同继承方式下基类成员访问属性的变化情况。
表5.1 不同继承方式下基类成员的访问属性说明:该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。
其余单元格内容为基类成员在派生类中的访问属性。
从表中可以看出:(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。
(2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。
(3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。
(4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。
需要注意的是:保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。
在同一类中私有成员和保护成员的用法完全一样。
3.派生类能否直接访问基类的私有成员?若否,应如何实现?派生类不能直接访问基类的私有成员。
具体实现方式:(1) 在类定义体中增加保护段为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。
保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。
这样,既方便了派生类的访问,又禁止外界对它的派生类访问。
第5章 继承和派生类
2010/9/18
第5章 继承和派生类
程序运行结果: x=4 y=5 l=6 w=8 程序分析: 通过公有继承方式,从BaseClas类得到DerivedClass类。 派生类DerivedClass只有一个基类,所以是单继承。基类 BaseClass定义了两个数据成员,3个成员函数。派生类 DerivedClass定义了两个数据成员,3个成员函数。通过 继承,派生类DerivedClass拥有4个数据成员:x、y、l和 w,6个成员函数:setx ( )、sety ( )、setl ()、setw ( )、 displayxy ( )、displaylw( )。
2010/9/18
面象对象程序设计
第5章 继承和派生类
class Father:private Grandfather //中间类:Grandfather的 公有派生类, //Son的基类 { public: void test() { b1=10; //可以访问,因b1改为private b2=20; //可以访问,因b2改为private b3=30; //不可访问, 因b3改为不可访问 } };
2010/9/18
面象对象程序设计
第5章 继承和派生类
5.1.2 继承的种类
在C++语言中,一个派生类既可以从一个基类派生,也可 以从多个基类派生。从一个基类派生的继承被称为单继承。 单继承形成的类层次是一个倒挂的树,如图5.2所示。从 多个基类派生类的继承被称为多继承。多继承形成的类层 次是一个有向无环图(DAG),如图5.3所示。在图5.2中, 输入设备是基类,从它派生出了3个派生类:键盘类、鼠 标类和扫描仪类。在图5.3中,从教师类和干部类派生出 校长类,即校长类有两个基类。
第五部分继承与类的派生教学课件
2 类外访问属性 类成员的类外访问是指在类对象定义域外访问对象 的类成员。因此,派生类成员在类定义中声明的访 问属性确定了派生类成员的类外访问属性:
⑴ 基类成员的访问属性 ① 私有成员:不允许被访问,与派生类从基类 的继承方式无关。 ② 公有成员:依据继承方式的不同,在基类中 被设定的公有属性会发生不同的变化。 ·私有继承:基类的公有成员变为派生类的 私有成员,因此在类外不允许被访问。 ·公有继承:基类的公有成员在派生类中仍 保持公有属性,因此在类外允许被访问。
一个链表结构的整数集合可以看成是不含重复元素
的特殊整数链表,因此整数集合类可以从整数链表类
派生。整数集合类在继承了整数链表类的所有成员的
基础上,需要新增加一个能指示集合中元素个数的数
据成员,同时还需要重新定义整数链表类的插入操作
insert,禁止重复元素被插入。
class set : public list
由于派生类的成员分为继承的基类成员和自身的新 增成员两种,这两种成员的类内访问属性是有所区 别的。 ⑴ 基类成员的访问属性
封装性所限定的类成员类外访问权限确定了基类 成员在派生类定义中被访问的限定原则:
① 私有成员:不允许被访问,与派生类从基类 的继承方式无关。
② 公有成员:允许被访问,与派生类从基类的 继承方式无关。
class Customer { private:
char name[15]; int age; char sex[8]; double income; public: void print(); };
// 姓名 // 年龄 // 性别 // 收入
第5章 继承与派生总结
private 成员 protected 成员 public 成员
派生类
不可访问 protected 成员 protected 成员 private 成员 protected 成员 public 成员
8
简单派生类的构造函数
派生类构造函数(总参数列表): 基类构造函 数(参数列表)
派生类中新增数据成员初始化语句
}
注意:调用基类、子对象的构造函数的顺序是按 照声明派生类时基类、子对象出现的顺序来调用 的。
12
5.6 多重继承
(三)多重继承引起的二义性问题 1、两个基类有同名成员
2、两个基类和派生类有同名成员
3、两个直接基类都继承于同一基类
13
5.6 多重继承
(四)虚基类 虚基类的作用:可以使得在继承间接共同 基类时只保留一份成员。 虚基类是在派生类的声明过程中声明的, 一般形式为: class 派生类名:virtual [继承方式] 基类名 {
继承与组合
20
目标
理解派生和继承的相关概念; 掌握派生类的声明方式
掌握派生类的构成和成员的访问属性;
掌握派生类构造函数和析构函数的使用方 法; 掌握多重继承的方法; 理解基类和派生类的转换方法; 理解继承与组合的含义。
21
练习
以点(point)类为基类,派生类圆类,圆由圆心 和半径定义。派生类操作判断任一坐标点是在图 形内,还是在图形的边缘上,还是在图形外。
5.8 继承与组合
继承建立了派生类与基类之间的一种“是” 的关系,是纵向的。 组合建立了成员类和组合类(复合类)之 间的一种“有”的关系,是横向的。
19
总结
本章主要讲授内容 继承和派生的概念
C++05继承和派生类
B1,B2的基类 A的派生类 C1,C2,C3的基类
A A的派生类(单继承) C3的基类
B1
B2
B1的派生类
C1
C2 C3
B1,B2的派生类(多继承)
图11-1 类之间的继承与派生关系
4
1.1 派生类的定义格式
单继承的定义格式如下: class<派生类名> :<继承方式><基类名> { public: //派生类新定义成员 members; <private:> members; <protected:> members; };
19
#include <iostream.h>
class A
{ public: A(){cout<<“A Construct1”<<endl;} A(int i){x1= i;cout<<“A Construct2”<<endl;} void dispa(){cout<<“x1=”<<x1<<endl;} private:int x1; }; class B:public A { public: B(){cout<<“B Construct1”<<endl;} B(int i):A(i+10){x2= i;cout<<“B Construct2”<<endl;} void dispb(){dispa() ;cout<<“x2=”<<x2<<endl;} private:int x2;
结果: A Construct2 B Construct2 x1=12
第5章 继承与派生
15
int main() { Base b1(5, 6, 7); //cout<< b1.a; //cout<<b1.b; 无法访问对象的保护成员 cout<<b1.c<<endl; cout<<b1.geta()<<endl; Sub s1(11,15,19,22); s1.test(); s1.c = 200; s1.fun3(); return 0; }
2
单继承
图5.1 单继承
图5.2 类的层次树型结构图
3
多继承
图5.3 多继承
图5.4 单继承与多继承
4
class Student { private: int number; char name[20]; public: Student() { number=0; name[0]=’\0’; } Void SetValue(int n,char *s1) { number=n; Strcpy(name,s1); } void Print() { cout<<”Number:”<<number<<endl; cout<<”Name:”<<name<<endl; } };
第 5章
继承和派生
本章重点: 继承与派生的概念; 派生类的构造函数和析构函数的执行顺序与规 则; 多继承的声明与实现; 基类成员访问原则; 赋值兼容性; 虚基类的概念 ;
1
5.1继承与派生的概念
继承是面向对象程序设计中重要的特性 继承主要是指在己有类(基类)的基础上创建新类 的过程,这个新类就是派生类 派生类包含基类的成员,包括所有的数据和操 作,而且还可以增加新的成员
5 继承与派生
接口
}
私有数据 x
Setx() base Getx() Showx()
}
derived Setx() Getx() Showx() Sety() Gety() Showy()
x
y
void main() { derived obj; obj.setx(10); obj.showx(); obj.sety(); obj.showx(); }
class B { private: int i; protected: int j; public: int k;}; class D: public B {public: void f() { i=1;//cannot access j=2; k=3; } }; void main() { B b; b.i =1;//cannot access b.j=2; //cannot access b.k=3;}
class C:public B { public: C( ); C(int i,int j); ~C( ); void Print( ) const; private: int c; };
C::~C( ) { cout<<"C's destructor"<<endl; } void C::Print( ) const { B::Print( ); cout<<c<<endl; } int main( ){
class Rectangle: public Point { //派生类声明 public: //新增公有函数成员 void initR(float xx, float yy, float ww, float hh) {initP(xx,yy);w=w;h=h;}//调用基类公有成员函数 float getH( ) {return h;} float getW( ) {return w;} float area() {return h*w;} private: float w,h; }; //新增私有数据成员
C++程序设计课件 第5课 类的继承与派生
第5课类的继承与派生===================================================================== 复习===================================================================== 1、指针(test1)#include <iostream>#include <cstdlib>using namespace std;int main(){int* p1=new int;*p1=100;cout<<*p1<<endl;cout<<p1<<endl;cout<<&p1<<endl;delete p1;//====================C用法===================cout<<endl;int* p2=(int*)malloc(sizeof(int));*p2=200;cout<<*p2<<endl;cout<<p2<<endl;cout<<&p2<<endl;free(p2);return 0;}--------------------------------------------------------------------- 2、引用(test2)#include <iostream>using namespace std;void add(char& m){m=m+2;}int main(){char c;cout<<"input char:";cin>>c;add(c);cout<<"the char is:"<<c<<endl;return 0;}=====================================================================一、继承与派生先来看一张动物的种属图,如图5-1所示。
第5章 类的派生与继承
第5章 类的派生与继承
class BaseClass //基类 {
int vl,v2; }; class DerivedClass : public BaseClass //派生类 {
int v3; };
第5章 类的派生与继承
二、派生类的定义与大小 1、派生类的定义 从基类派生派生类的一般格式: class派生类名:继承方式说明符 基类名 {
编程小技巧:同学们可以将鼠标放置于类中的任何一个成 员或者函数上,编程软件会提示,对应的访问权限,这个方法在 继承编程中特别好用。
第5章 类的派生与继承
我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则: 公有继承(public):当一个类派生自公有基类时,基类的公
第5章 类的派生与继承
C++程序设计
第5章 类的派生和继承
第5章 类的派生与继承
本章内容
类的继承与类的派生 访问控制 派生类的构造函数和析构函数 类之间的关系 多层次派生 基类与派生类指针的相互转换
第5章 类的派生与继承
第一节 类的继承与类的派生
常考知识点: 继承派生基本概念 继承派生在C++中起到的作用 派生类定义的方法 派生类从基类继承的元素有哪些 继承关系中友元和静态成员变量的派生特点 单继承、多重继承的概念以及异同 派生的层次
第5章 类的派生与继承
1、继承:在一个已存在的类的基础上建立一个新的类,称 为继承
2、派生:从已有的类(父类)产生一个新的子类,称为类的 派生
3、单继承:一个派生类只从一个基类派生,这称为单继承 4、多继承:一个派生类有两个或多个基类的称为多重继承
第5章继承与派生.docx
第 5 章继承与派生5.1 继承与派生的概念图 5.1图 5.2图 5.3图5.425.2 派生类的声明方式5.3 派生类的构成数据结构 (C++版 )图5.5图5.65.4 派生类成员的访问属性5.4.1 公用继承C++ 面向对象程序设计3 5.4.2 私有继承图5.75.4.3 保护成员和保护继承图5.84数据结构 (C++版 ) 5.4.4 多级派生时的访问属性图 5.9 5.5 派生类的构造函数和析构函数5.5.1 简单的派生类的构造函数图 5.10图 5.11 5.5.2 有子对象的派生类的构造函数C++ 面向对象程序设计5图5.125.5.3 多层派生时的构造函数图5.135.5.4 派生类构造函数的特殊形式5.5.5 派生类的析构函数5.6 多重继承5.6.1 声明多重继承的方法5.6.2 多重继承派生类的构造函数5.6.3 多重继承引起的二义性问题6数据结构 (C++版 )图5.14图5.15图5.16图5.17图5.18C++ 面向对象程序设计7图5.19图5. 205.6.4 虚基类1.虚基类的作用图5.218数据结构 (C++版 )图 5.22图 5.23图 5.242.虚基类的初始化C++ 面向对象程序设计9图5.253.虚基类的简单应用举例5.7 基类与派生类的转换图5.26图5.2710数据结构 (C++版 )5.8 继承与组合5.9 继承在软件开发中的重要意义习题1.将例 5.1 的程序片段补充和改写成一个完整、正确的程序,用公用继承方式。
在程序中应包括输入数据的函数,在程序运行时输入num,name,sex,age,addr的值,程序应输出以上 5 个数据的值。
2.将例 5.2 的程序片段补充和改写成一个完整、正确的程序,用私有继承方式。
在程序中应包括输入数据的函数,在程序运行时输入num,name,sex,age,addr的值,程序应输出以上 5 个数据的值。
3.将例 5.3 的程序修改、补充,写成一个完整、正确的程序,用保护继承方式。
第五章 类的继承与派生
//save as car.h #include "vehicle.h" class car : public vehicle { //派生类car(轿车) public: void setcar(int aw, int ats, float ap, int anc, int ahp) {setvehicle(aw,ats,ap); //调用基类的函数初始化 numbercylinders=anc; horsepower=ahp; } void print( ) { //重定义print( ) vehicle::print( ); //调用基类的函数 cout << "\n cylinders:" << numbercylinders; cout << "\n horsepower:" << horsepower;} private: int numbercylinders; //汽缸数 int horsepower; //马力 };
子类特有的部分
子类名
public、protected 和 private分别表示公有继承、保护 继承和私有继承,定义派生类时三选一。
7
第五章 类的继承与派生
(3)说明 ①public继承 最常见的派生方式。基类成员的访问权限在派生类中保 持不变,派生类成员函数不可直接访问基类的private成员, 可通过基类的公有成员函数或保护成员函数访问。 ②private继承 基类中的所有成员在派生类中都将变为private成员。 派生类成员函数不可直接访问基类的private成员,但可直 接访问基类的public、protected成员,并通过它们访问基 类的private成员。 ③protected继承 基类的public成员在派生类中变为protected成员,基类 的protected和private成员在派生类中保持原来的访问权限。 8
类的继承与派生 谭浩强C++ppt课件
基类和派生类
对于保护继承方式与私有继承方式的情况基本相同。两者的区别就在于,基类的公有成 员与保护成员在私有继承的方式下,在派生类中不允许再往下继承,而保护继承方式则允许 继续往下传递。
可将可见性理解为可访问性。关于可访问性的另外一种规则中,称派生类对象对基类的 访问为水平访问,称派生类的派生类对基类的访问为垂直访问。则上述讨论可总结如下:
二.派生类的三种继承方式 公有继承(public)、私有继承(private)和保护继承(protected)是常用的三种继承
方式。 ⒈ 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的
状态,而基类的私有成员仍然是私有的。 ⒉ 私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这
个派生类的子类所继承与访问。
5
基类和派生类
⒊ 保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被 它的派生类成员函数或友元访问,而这种继承关系还可向其子类进行传递。基类的私有成员仍然 是私有的。 为了进一步理解三种不同继承方式在其成员的可见性方面的区别,下面从三种不同角度进 行讨论。
生类的关系是相对而言的。
8
基类和派生类
这就意味着:一个基类可以是另一个基类的派生类,这样便形成了复杂的继承结构,出 现了类的层次。一个基类派生出一个派生类,它又可作为另一个派生类的基类,则原来的基 类为该派生类的间接基类。其关系如右图所示。
6
基类和派生类
⑵ 基类成员对派生类成员函数的可见性: 公有成员与保护成员可见,而私有成员不可见。这里保护成员等同于公有成员。
第5章-派生类与继承PPT优秀课件
继承是面向对象程序设计的一个重要特性。
它允许在既有类的基础上创建新的类,新类可以从一 个或多个既有类中继承函数和数据,而且可以重新定 义或加进新的数据和函数,从而形成类的层次或等级。
既有类称为基类或父类,在它基础上建立的新类称为 派生类或子类。
公有派生和私有派生的访问特性
基类成员 派生方式 派生类成员
外部函数
基类私有成员
private 不可访问
public 不可访问
不可访问
不可访问
基类公有成员
private
public
可访问
可访问
不可访问
可访问
派生类的概念
5.1.3 保护成员
保护成员:即protected成员,是C++提供的具有另一种访问 属性的成员
}; class derive: public base {
int c;
C++规定:基类的保护成 public:
员被派生类继承之后,若
void setc(int n)
为公有派生,则基类中的 保护成员在派生类中也为
{ c=n; } void showabc() { cout<<a<<“ ”<<b<<“ ”<<c<<endl; }
int x; public:
void setx(int n) { x=n; } void showx() { cout<<x<<endl; } }; class derived : public base { int y; public: void sety( int m) { y=m; } void showy() { cout<<y<<endl; } }; int main() { derived obj; obj.setx(10); obj.sety(20); obj.showx(); obj.showy(); return 0; }