第8章继承与派生
合集下载
第八章-继承与派生PPT课件

• 方法二:面向对象?
– class circle 圆形
– class rectangle 矩形
shape
– class triangle 三角形
– 基类: class shape
• 色彩 color • 位置 (x, y)
circle rectangle triangle
14
class Tshape { private:
}; 27
3.保护继承
基类
public: protected:
private:
派生类成员 函数可以访问
基类 protected 成员的
属性
派生类
prote?cted prote?cted
priv?ate
派生类对象
1.• 基私类有成继员承公的有派成生员类和保定护义成形员式在:派生类中变成保护类型的,基类的私 2.cl有派as成生s员类派属的生性成不员类变函名;数:pro可t以ec访te问d基基类类的公名有成员和保护成员,不能访问
– DrawTri (int x, int y, char color, int side);
– DrawRect (int x, int y, char color, int length, i nt width)
– DrawCircle(int x, int y, char color, int Radius)
29
继承方式影响访问控制
基类存取 派生类继承的 方式
基类成员的 访问属性
继承类型
public protected private
public:
public protected private
protected: private:
第8章_继承和派生

};
派生类中含有对象成员时,其构造函数的声明格式如下:
派生类的构造函数名称(参数表): 基类的构造函数名(参数表),
对象成员名1(参数表),…对象成员名N(参数表)
{
//…
//派生类构造函数体
}
class Circle2 :public Point
{
double radius;
Point P1; //基类Point的对象成员P1
{
protected
}; void main() { son sonobj;
sonobj.get(); }
8.3 派生类的构造函数和析构函数
派生类的构造函数名称(参数表):基类的构造函数名(参数表) {
… }
class Point
{ int x,y;
public:
Point(int a,int b) //基类的构造函数
Circle (double r,int a,int b):Point(a,b)
//派生类的构造函数
{ radius =r;
cout<<”Constructing Circle class \n”;
}
~ Circle () //派生类的析构函数
{ cout<<”Destructing Circle class \n”; }
使用protected声明的称为保护成员。任何一个类的保护成员 仅可以被其自己和派生类的所有非静态成员函数和友元函数直 接访问,也就是说其他的外部函数是不能访问它的。因此,对 于那些既要对外界隐藏,又要能被派生类访问的成员,可以将 它们声明为保护成员。
8.2.3三种派生方式的定义
class 派生类名 : 派生存取说明符 基类名 { //派生类新增的数据成员和成员函数 }; 1.私有(private)派生
第8章 继承与派生

允许将派生类的对象赋值给基类的对象。 允许将派生类的对象赋值给基类的对象。
拷贝派生类 基类对象 的基类子对 内存映象 象
派 生 类 对 象 内 存 映 象
从基类继承 的数据成员
派生类新增 的数据成员
不允许将基类的对象赋值给派生类的对象。 不允许将基类的对象赋值给派生类的对象。
派 派 生 生 类 类 对 对 象 象 内 内 存 存 映 映 象 象
第8章 继承与派生
(1) 继承的基本概念
继承是一种类与类之间的关系, 继承是一种类与类之间的关系,这种关系允许在既 有类的基础上创建新的类。也就是说, 有类的基础上创建新的类。也就是说,定义新类时可以 从一个或多个既有类中继承(即拷贝) 从一个或多个既有类中继承(即拷贝)所有的数据成员 和函数成员, 和函数成员,然后加上自己的新成员或重新定义由继承 得到的成员。 得到的成员。 继承形成一种类的层次关系, 继承形成一种类的层次关系,既有类成为基类或父 以它为基础建立的新类称为派生类、导出类或子类。 类,以它为基础建立的新类称为派生类、导出类或子类。
表8.1不同继承方式下的基类成员在派生类中的访问权限 不同继承方式下的基类成员在派生类中的访问权限
继承方式 基类中访问权限 public protected private 派生类中访问权限 public protected 不可访问 private private 不可访问 protected protected 不可访问
公有继承
私有继承
public protected private
保护继承
public protected private
保留字protected的意义 保留字protected的意义
通常希望派生类定义的新方法能够操纵基 类的数据成员, 类的数据成员,也就是说产生了从基类外 部访问基类 ( 私有 ) 数据成员的需求 。 C++通过 通过protected访问权限提供了一种有 通过 访问权限提供了一种有 条件地打破封装的机制, 条件地打破封装的机制,即只向自己的后 代开放数据成员的访问权限。 代开放数据成员的访问权限。由于封装的 目的是修改的局部化, 目的是修改的局部化,即只要类的接口不 变,类可以对内部的数据成员类型及函数 实现代码作任意修改。封装打破后, 实现代码作任意修改。封装打破后,类就 不能再作这种随意的修改,否则, 不能再作这种随意的修改,否则,派生类 成员函数继续以修改前的方式工作必然会 发生错误。为此, 发生错误。为此,基类将可以让派生类修 改的数据成员说明为保护的,是为了提醒 改的数据成员说明为保护的,是为了提醒 基类自己这些成员要么不修改, 基类自己这些成员要么不修改,要么连同 所有的派生类一起修改。 所有的派生类一起修改。 所以作为访问控制权限的protected应该 所以作为访问控制权限的 应该 出现在基类中而不一定出现在派生类中。 出现在基类中而不一定出现在派生类中。
《继承性和派生性》PPT课件

继承方式: public private
protected 直接继承
(P)
6
8.1.2 派生类的三种继承方式(续)
表:继承对基类成员的访问能力
公有继承 私有继承 保护继承
J PHV J PHV J PHV
私有 成员
公有 成员
√√√√√√ (私)
√√ (保)
√
保护 成员
√
√
√
(私)
√
√
精选课件ppt
<派生类新定义成员> };
2、多继承
class <派生类名>:<继承方式1> <基类名1>, <继承方式2> <基类名2>...
{ <派生类新定义成员>
};
精选课件ppt
3
8.1.1 派生类的定义格式(续)
3、继承方式 public:公有继承;
private:私有继承;
protected:保护继承; 作用:控制基类中声明的成员在多大的范围内 能被派生类的用户访问;
7
8.1.2 派生类的三种继承方式(续)
说明: 私有成员不参与继承的访问控制;
基类实例(J):与继承方式无关,遵循访问控制 权限的定义;
直接继承(P):可以访问基类中的公有成员和 保护成员,但成员的权限随继承方式而改变;
水平访问(H)=P+J;
垂直访问(V)=P+P;
保护成员:在垂直访问(V)时相当于公有成员, 在水平访问(H)时相当于私有成员;
14
8.1.2 派生类的三种继承方式(续)
{ Location::Move(xOff,yOff); }
int GetX() {return Location::GetX();}
第8章 派生与继承

3
4
5
保护继承(public)
保护继承方式创建的派生类对基类各种成 员访问权限如下 :
– 基类的公有成员和保护成员都相当于派生 类的保护成员,派生类可以通过自身的成 员函数或其子类的成员函数访问他们 – 对于基类的私有成员,无论派生类内部成 员或派生类使用者都无法直接访问
[例] 分析程序,回答问题
void main( )
{ B d1; d1.f(6); d1.g( );
d1.h( );
}
回答下列问题: 1. 执行该程序时,哪个语句会出现编译错? 为什么? 2. 去掉出错语句后,执行该程序后输出结 果如何? 3. 程序中派生类B是从基类A继承来的,这 种缺省继承方式是哪种继承方式? 4. 派生类B中,A::f的含义是什么? 5. 将派生类B的继承改为公有继承方式该 程序输出什么结果?
8.3 单继承、多继承与继承链
从一个基类派生的继承称为单继承 从多个基类派生的继承称为多继承 单继承 多继承
8.3.1 单继承
每一个类可以有多个派生类 每一个派生类只能有一个基类从而形成 树形结构
8.3.2 成员访问权限的控制
公有继承public 私有继承private 保护继承protected
Ans:
1 编译时出错行是: cout<<"name:"<<name<<endl; 错误信息提示name是私有成员不能访问。 2 在类A中,将private改写为protected。这 样就可以通过编译。 派生类可访问基类的保护部分,并把它作 为派生类的公有部分;但程序其他部分把 name作为私有成员。例如在main中,不能 运行 strcpy(s1,) 3 执行修改后的该程序输出如下结果: wang li
第08章 继承与派生

在存在名称覆盖的情况下直接使用派生类的对象访问的是派生类中的成员通过基类对象访问的是基类中的成员见示例程序多重继承中的二义性一般来说一个类中的成员应该是唯一的同名函数可以通过参数列表加以区分此谓函数重载对于多重继承中的派生类如果多个基类中拥有相同的成员那么派生类在继承各个基类的成员之后该派生类中将出现不唯一的成员此谓多重继承中的二义性程序不访问派生类的二义性成员时不会报编译错误但一旦访问派生类的二义性成员将会报编译错误见示例程序多重继承中二义性的解决办法在派生类中定义相同成员覆盖基类中的成员
作业
教材P270-1.填空题之(1)至(6)
有派生时”改为“ (4)之 注:(4)之“当私有派生时”改为“当公有派生 时”
类名(形参总表):基类1名(实参表),…,成员变量1名(实参表),…{…}
各个构造函数的调用次序是:首先按照类定义中基类的次 序,调用各个基类的构造函数,其次按照类定义中成员的 次序,调用各个成员的构造函数,最后执行派生类构造函 数中的代码。析构函数的调用次数与之相反(见示例程序)
类型兼容
类型兼容是指在公有继承的情况下,一个派生类 对象可以作为基类的对象来访问。类型兼容有三 种使用场景:
手脑并用
做到“上机、上机、再上机”
切忌浮躁
如果你愿意利用5年时间来成为高手,那么你只要两 三年就会成为高手,如果你想一年就成为高手,那 么你5年也成不了高手
继承/派生概述
现实世界中的许多事物,它们之间具有“一般与特殊” 的关系。例如:人是一个群体,学生也是一个群体,某 个具体的学生,他/她既具有人的特征也具有学生的特征 在面向对象的程序设计中, “一般与特殊”的关系使用 继承/派生机制实现,该机制利用已有的“一般”类来定 义新的“特殊”类,使得新类不仅拥有自己的属性和操 作,而且也拥有原有类的属性和操作,实现了代码级别 上的复用 原有类称为基类(Base Class)或父类(Super Class),新 类称为派生类(Derived class)或子类(Sub Class) 子类拥有父类属性和操作这一过程称为继承(Inherit); 由父类产生子类的过程称为派生(Derive)
作业
教材P270-1.填空题之(1)至(6)
有派生时”改为“ (4)之 注:(4)之“当私有派生时”改为“当公有派生 时”
类名(形参总表):基类1名(实参表),…,成员变量1名(实参表),…{…}
各个构造函数的调用次序是:首先按照类定义中基类的次 序,调用各个基类的构造函数,其次按照类定义中成员的 次序,调用各个成员的构造函数,最后执行派生类构造函 数中的代码。析构函数的调用次数与之相反(见示例程序)
类型兼容
类型兼容是指在公有继承的情况下,一个派生类 对象可以作为基类的对象来访问。类型兼容有三 种使用场景:
手脑并用
做到“上机、上机、再上机”
切忌浮躁
如果你愿意利用5年时间来成为高手,那么你只要两 三年就会成为高手,如果你想一年就成为高手,那 么你5年也成不了高手
继承/派生概述
现实世界中的许多事物,它们之间具有“一般与特殊” 的关系。例如:人是一个群体,学生也是一个群体,某 个具体的学生,他/她既具有人的特征也具有学生的特征 在面向对象的程序设计中, “一般与特殊”的关系使用 继承/派生机制实现,该机制利用已有的“一般”类来定 义新的“特殊”类,使得新类不仅拥有自己的属性和操 作,而且也拥有原有类的属性和操作,实现了代码级别 上的复用 原有类称为基类(Base Class)或父类(Super Class),新 类称为派生类(Derived class)或子类(Sub Class) 子类拥有父类属性和操作这一过程称为继承(Inherit); 由父类产生子类的过程称为派生(Derive)
《继承和派生》课件

时提供默认值。
派生类的析构函数
派生类析构函数在销毁派生类对象时 自动调用,用于释放派生类所占用的 资源。
派生类析构函数可以包含代码,用于 清理派生类所占用的资源。
派生类析构函数可以访问基类的析构 函数,通过使用`this`关键字调用基类 析构函数。
派生类析构函数可以重载基类析构函 数,以便在销毁派生类对象时执行特 定的操作。
基类析构函数的调用
在派生类的析构函数中,可以通过使用`this`关键字调 用基类的析构函数,以确保基类资源得到正确释放。
输标02入题
如果在派生类的析构函数中没有显式调用基类的析构 函数,则编译器会自动调用基类的默认析构函数。
01
03
在某些情况下,可能需要显式调用基类的析构函数, 以确保资源得到正确释放。例如,当基类包含动态分
02 继承的方式
公有继承
总结词
公有继承是指子类可以访问父类的公有成员。
详细描述
在公有继承中,子类可以访问父类的公有成员(即不加任 何修饰符的成员),这些成员在子类中保持公有属性。子 类可以继承和使用父类的公有成员,包括函数、变量、常 量等。
总结词
公有继承是实现代码复用的一种方式。
详细描述
通过公有继承,子类可以继承父类的公有成员,从而避免 重复编写相同的代码。这有助于提高代码的复用性和维护 性。
注意事项
虚函数和纯虚函数的使用 应合理规划,避免过度使 用导致程序复杂度和维护 成本增加。
继承和派生的效率问题
继承
通过共享已存在的代码, 减少代码冗余。但也可能 导致内存浪费和性能下降 。
派生
通过扩展已有类,增加新 功能或修改已有功能。但 也可能导致内存消耗增加 和性能下降。
注意事项
派生类的析构函数
派生类析构函数在销毁派生类对象时 自动调用,用于释放派生类所占用的 资源。
派生类析构函数可以包含代码,用于 清理派生类所占用的资源。
派生类析构函数可以访问基类的析构 函数,通过使用`this`关键字调用基类 析构函数。
派生类析构函数可以重载基类析构函 数,以便在销毁派生类对象时执行特 定的操作。
基类析构函数的调用
在派生类的析构函数中,可以通过使用`this`关键字调 用基类的析构函数,以确保基类资源得到正确释放。
输标02入题
如果在派生类的析构函数中没有显式调用基类的析构 函数,则编译器会自动调用基类的默认析构函数。
01
03
在某些情况下,可能需要显式调用基类的析构函数, 以确保资源得到正确释放。例如,当基类包含动态分
02 继承的方式
公有继承
总结词
公有继承是指子类可以访问父类的公有成员。
详细描述
在公有继承中,子类可以访问父类的公有成员(即不加任 何修饰符的成员),这些成员在子类中保持公有属性。子 类可以继承和使用父类的公有成员,包括函数、变量、常 量等。
总结词
公有继承是实现代码复用的一种方式。
详细描述
通过公有继承,子类可以继承父类的公有成员,从而避免 重复编写相同的代码。这有助于提高代码的复用性和维护 性。
注意事项
虚函数和纯虚函数的使用 应合理规划,避免过度使 用导致程序复杂度和维护 成本增加。
继承和派生的效率问题
继承
通过共享已存在的代码, 减少代码冗余。但也可能 导致内存浪费和性能下降 。
派生
通过扩展已有类,增加新 功能或修改已有功能。但 也可能导致内存消耗增加 和性能下降。
注意事项
08第八章继承与派生

一个基类成员在基类中的访问属性和在派生类中的访问属 性可能是不同的。私有基类的成员在私有派生类中的访问属 性见书中表8.2。 表8.2 私有基类在派生类中的访问属性
私有基类成员 私有成员 公有成员 保护成员来自在派生类中的访问 属性
不可访问 私有 私有
C++程序设计基础
8.4.3 保护成员和保护继承
由protected声明的成员称为“受保护的成员”,或简 称“保护成员”。
此外,在声明派生类时,一般还应当自己定义派生类的构 造函数和析构函数,因为构造函数和析构函数是不能从基类 继承的。
C++程序设计基础
实际上,并不是把基类的成员和派生类自己增加的成员简单 地加在一起就成为派生类。构造一个派生类包括以下3部分工 作:
(1)从基类接收成员。 派生类把基类全部的成员(不包括构造函数和析构函数)接收 过来,也就是说是没有选择的,不能选择接收其中一部分成员, 而舍弃另一部分成员。 要求我们根据派生类的需要慎重选择基类,使冗余量最小。 事实上,有些类是专门作为基类而设计的,在设计时充分考虑 到派生类的要求。 (2)调整从基类接收的成员。 接收基类成员是程序人员不能选择的,但是程序人员可以对 这些成员作某些调整。 (3)在声明派生类时增加的成员。 这部分内容是很重要的,它体现了派生类对基类功能的扩展。 要根据需要仔细考虑应当增加哪些成员,精心设计。
派生类中不可访问的成 员
在派生 类中 可以
可以
可以
不可以
在派生类 在下层公有派
外部
生类中
可以
可以
不可以
不可以
不可以
不可以
不可以
不可以
C++程序设计基础
8.5 派生类的构造函数
私有基类成员 私有成员 公有成员 保护成员来自在派生类中的访问 属性
不可访问 私有 私有
C++程序设计基础
8.4.3 保护成员和保护继承
由protected声明的成员称为“受保护的成员”,或简 称“保护成员”。
此外,在声明派生类时,一般还应当自己定义派生类的构 造函数和析构函数,因为构造函数和析构函数是不能从基类 继承的。
C++程序设计基础
实际上,并不是把基类的成员和派生类自己增加的成员简单 地加在一起就成为派生类。构造一个派生类包括以下3部分工 作:
(1)从基类接收成员。 派生类把基类全部的成员(不包括构造函数和析构函数)接收 过来,也就是说是没有选择的,不能选择接收其中一部分成员, 而舍弃另一部分成员。 要求我们根据派生类的需要慎重选择基类,使冗余量最小。 事实上,有些类是专门作为基类而设计的,在设计时充分考虑 到派生类的要求。 (2)调整从基类接收的成员。 接收基类成员是程序人员不能选择的,但是程序人员可以对 这些成员作某些调整。 (3)在声明派生类时增加的成员。 这部分内容是很重要的,它体现了派生类对基类功能的扩展。 要根据需要仔细考虑应当增加哪些成员,精心设计。
派生类中不可访问的成 员
在派生 类中 可以
可以
可以
不可以
在派生类 在下层公有派
外部
生类中
可以
可以
不可以
不可以
不可以
不可以
不可以
不可以
C++程序设计基础
8.5 派生类的构造函数
第八章 继承与派生

一般来说,公有派生是绝对主流。
公有派生与私有派生
1. 公有继承(public)。 公有继承的特点是基类的公有成员和保护成员作为派生 类的成员时,它们都保持原有的状态,而基类的私有成员仍 然是私有的。 2. 私有继承(private)。 私有继承的特点是基类的公有成员和保护成员作为派 生类的私有成员,并且不能被这个派生类的子类访问。
基类 派生类 基类 public public Protected protected private private private 不可见 private 派生 派生类 protected 基类 public protected private 派生类 public proteced
不可见
不可见
在派生类对象外 访问派生类对象 的基类成员
可直接访问 不可直接访问 不可直接访问 不可直接访问 不可直接访问 不可直接访问
公有派生
私有派生
(1)在公有继承时,派生类的对象可以访问基类中的公有成 员;派生类的成员函数可以访问基类中的公有成员和保护成员。 这里,一定要区分清楚派生类的对象和派生类中的成员函数对 基类的访问是不同的。 (2)在私有继承时,基类的成员只能由直接派生类访问,而 无法再往下继承。
继承与派生的概念 派生类的构造函数与析构函数 多重继承与派生类成员标识 虚基类 类层次中成员名的作用域 类层次中类转换规则 多重继承的应用例子 MFC基础类及其层次结构
继承与派生的概念
层次概念是计算机的重要概念。通过继承(inheritance)的 机制可对类(class)分层,提供类型/子类型的关系。C++通过 类派生(class derivation)的机制来支持继承。继承是类之间定 义的一种重要关系。定义类B时,自动得到类A的操作和数据属性, 使得程序员只需定义类A中所没有的新成分就可完成在类B的定义, 这样称类B继承了类A,类A派生了类B,A是基类(父类),B是 派生类(子类)。这种机制称为继承。 称已存在的用来派生新类的类为基类(base class) ,又称 为 父 类 。 由 已 存 在 的 类 派 生 出 的 新 类 称 为 派 生 类 ( derived class) ,又称为子类。派生类可以具有基类的特性,共享基类 的成员函数,使用基类的数据成员,还可以定义自己的新特性, 定义自己的数据成员和成员函数。基类和派生类的集合称作类继 承层次结构(hierarchy) 在C++语言中,一个派生类可以从一个基类派生,也可以从 多个基类派生。从一个基类派生的继承称为单继承;从多个基类 派生的继承称为多继承。下图反映了类之间继承和派生关系。
C++面向对象程序设计第8章 继承与派生

7
蚌埠学院计算机系
C++面向对象程序设计
class Studend1 可以看出,很多是重复的地方, 我们可以通过C++语言中的 { int num; //此行原来己有 继承机制,可以扩充和完善旧 char name[20]; //此行原来己有 的程序设计以适应新的需求。 char sex; //此行原来己有 这样不仅可以节省程序开发的 时间和资源,并且为未来程序 int age; 增添了新的资源。 char addr[20]; public: void display( ) ; //此行原来己有 {cout<<"num: "<<num<<endl; //此行原来己有 cout<<"name: "<<name<<endl;//此行原来己有 cout<<"sex: "<<sex<<endl; //此行原来己有 cout<<"age: "<<age<<endl; cout<<"address: "<<addr<<endl;} };
蚌埠学院计算机系
21
C++面向对象程序设计
【例8-3】定义类Point,然后定义类Point的派生类 Circle。 #include <iostream.h> class Point //定义基类,表示点 { private: int x; int y; public: void setPoint(int a, int b){ x=a; y=b; }; //设置坐标 int getX(){ return x; }; //取得X坐标 int getY(){ return y; }; //取得Y坐标 };
蚌埠学院计算机系
C++面向对象程序设计
class Studend1 可以看出,很多是重复的地方, 我们可以通过C++语言中的 { int num; //此行原来己有 继承机制,可以扩充和完善旧 char name[20]; //此行原来己有 的程序设计以适应新的需求。 char sex; //此行原来己有 这样不仅可以节省程序开发的 时间和资源,并且为未来程序 int age; 增添了新的资源。 char addr[20]; public: void display( ) ; //此行原来己有 {cout<<"num: "<<num<<endl; //此行原来己有 cout<<"name: "<<name<<endl;//此行原来己有 cout<<"sex: "<<sex<<endl; //此行原来己有 cout<<"age: "<<age<<endl; cout<<"address: "<<addr<<endl;} };
蚌埠学院计算机系
21
C++面向对象程序设计
【例8-3】定义类Point,然后定义类Point的派生类 Circle。 #include <iostream.h> class Point //定义基类,表示点 { private: int x; int y; public: void setPoint(int a, int b){ x=a; y=b; }; //设置坐标 int getX(){ return x; }; //取得X坐标 int getY(){ return y; }; //取得Y坐标 };
电子科技大学c 第八章继承与派生PPT课件

C 单继承
Z 多继承
9
单继承派生类
• 定义单继承派生类的语法格式:
class 派生类名 : <继承方式> 基类名{ ……//派生类新添加的成员
};
• “继承方式”可以是public、private、 以及 protected。
• 虽然继承了基类的所有成员,但是派生类 并非都能访问基类的所有成员,继承方式 会影响派生类对基类中各种成员的引用。
2020/12/3
10
公有派生类
• 在声明派生类时将继承方式指定为 public时,该类称为公有派生类。
class 派生类名 : public 基类名
{ ……//派生类新添加的成员
};
2020/12/3
11
• 基类的成员在公有派生类中的引用权限
基类
公有成员 私有成员
保护成员
公有派生类 公有成员 不可访问成员 保护成员
public: int v4; Derived(int a=0,int b=0){ v3=a;v4=b; } void func(){ int sum1=v1+v2+v3+v4; //错误 int sum2=v2+v3+v4; }
};
16
公有派生和私有派生的比较
基类
公有成员
私有成员 保护成员
公有派生类 公有成员 不可访问成员 保护成员
第八章 继承与派生
2020/12/3
1
派生类的引入
• C++的类提供了良好的模块分解技术, 也具有可重用软件所期望的品质:它们 是相似一致的模块,通过信息隐藏,将 它们的接口和实现清楚地分开来。
• 我们还希望在类的基础上能取得更好的 可重用性和可扩充性的目标。
第8章 继承和派生

1.private类成员 1.private类成员
一个类中的私有(private)成员(包括数据成员和成员函数) 一个类中的私有(private)成员(包括数据成员和成员函数) 只能被它们所在类的成员函数和友元函数访问, C++中类成员 只能被它们所在类的成员函数和友元函数访问,在C++中类成员 存取说明符缺省的情况下的存取特征都是私有的(private)。 存取说明符缺省的情况下的存取特征都是私有的(private)。
8.2Βιβλιοθήκη 派生类成员的访问控制既然派生类中包含基类成员和派生类自己增加的成员, 既然派生类中包含基类成员和派生类自己增加的成员,就 产生了这两部分成员的关系和访问属性的问题。 产生了这两部分成员的关系和访问属性的问题。在建立派 生类的时候, 生类的时候,并不是简单地把基类的私有成员直接作为派 生类的私有成员, 生类的私有成员,把基类的公用成员直接作为派生类的公 用成员。实际上, 用成员。实际上,对基类成员和派生类自己增加的成员是 按不同的原则处理的。 按不同的原则处理的。
2.基类与派生类 2.基类与派生类
交通工具
飞机
滑翔机
直升飞机
喷气式飞机
已存在的类(例如“交通工具” 称为“基类” 已存在的类(例如“交通工具”)称为“基类”或“父类”。 父类” 新建立的类(例如“飞机” 称为“派生类” 子类” 新建立的类(例如“飞机”)称为“派生类”或“子类”。
一个基类可以派生出多个派生类, 一个基类可以派生出多个派生类,每一个派生类又可以作 为基类再派生出新的派生类, 为基类再派生出新的派生类,因此基类和派生类是相对 而言的。 而言的。
//定义一个基类(Student类) //定义一个基类(Student类 定义一个基类 class Student { public: //姓名 char name[10]; //姓名 int age; //年龄 //年龄 //性别 char sex; //性别 //班级名称 char classname[20]; //班级名称 }; //定义一个派生类 GraduateStudent类 定义一个派生类( //定义一个派生类(GraduateStudent类) class GraduateStudent : public Student { public: //导师 char Advisorname[10]; //导师 //资格考试分 int qualifiergrade; //资格考试分 };
一个类中的私有(private)成员(包括数据成员和成员函数) 一个类中的私有(private)成员(包括数据成员和成员函数) 只能被它们所在类的成员函数和友元函数访问, C++中类成员 只能被它们所在类的成员函数和友元函数访问,在C++中类成员 存取说明符缺省的情况下的存取特征都是私有的(private)。 存取说明符缺省的情况下的存取特征都是私有的(private)。
8.2Βιβλιοθήκη 派生类成员的访问控制既然派生类中包含基类成员和派生类自己增加的成员, 既然派生类中包含基类成员和派生类自己增加的成员,就 产生了这两部分成员的关系和访问属性的问题。 产生了这两部分成员的关系和访问属性的问题。在建立派 生类的时候, 生类的时候,并不是简单地把基类的私有成员直接作为派 生类的私有成员, 生类的私有成员,把基类的公用成员直接作为派生类的公 用成员。实际上, 用成员。实际上,对基类成员和派生类自己增加的成员是 按不同的原则处理的。 按不同的原则处理的。
2.基类与派生类 2.基类与派生类
交通工具
飞机
滑翔机
直升飞机
喷气式飞机
已存在的类(例如“交通工具” 称为“基类” 已存在的类(例如“交通工具”)称为“基类”或“父类”。 父类” 新建立的类(例如“飞机” 称为“派生类” 子类” 新建立的类(例如“飞机”)称为“派生类”或“子类”。
一个基类可以派生出多个派生类, 一个基类可以派生出多个派生类,每一个派生类又可以作 为基类再派生出新的派生类, 为基类再派生出新的派生类,因此基类和派生类是相对 而言的。 而言的。
//定义一个基类(Student类) //定义一个基类(Student类 定义一个基类 class Student { public: //姓名 char name[10]; //姓名 int age; //年龄 //年龄 //性别 char sex; //性别 //班级名称 char classname[20]; //班级名称 }; //定义一个派生类 GraduateStudent类 定义一个派生类( //定义一个派生类(GraduateStudent类) class GraduateStudent : public Student { public: //导师 char Advisorname[10]; //导师 //资格考试分 int qualifiergrade; //资格考试分 };
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.掌握多重继承的概念、定义方法、多重继承派 生类构造函数的执行顺序。
先执行所有基类的构造函数(顺序按照定义派生 类时指定的各基关顺序) 再执行对象成员所在类的构造函数(顺序按照它 们在类中的声明顺序)
最后执行派生类构造函数体中的内容
授课内容
8.1 继承与派生 8.2 派生类的继承方式 8.3 派生类的构造函数和析构函数 自学内容
派生类构造函数的一般形式为: 派生类名::派生类名(参数总表):基类名1(参数表1) ,…,基类名n(参数表n), 内嵌对象名1(对象参数表1),…,内嵌对象名m(对象参 数表m) {
派生类新增加成员的初始化;
}
派生类与基类的析构函数没有什么联系,彼此独立,派生类 或基类的析构函数只作各自类对象消亡前的善后工作
类模版
template <class <类型参数>>
class <类名> {
……
};
上机练习题
1.声明一个Shape(形状)基类,它有两个派生类— —Circle(圆)和Square(正方形),要求(1 )根据给出圆心的坐标,计算圆的面积;(2) 根据给出正方形的中点坐标和一个顶点坐标,计 算该正方形的面积。
例8.5
一个基类有多个派生类
class Student : public Person { char m_strID[12]; char m_strClass[12]; public: Student(char *name,int age,char sex,char *ID,char *Class); void ShowMe(); };
静态成员
class MyClass {
int
};
m_nx;
static int m_nCount; intMyClass::m_nCount=0; MyClass MemberX, MemberY;
8.6 类模版
类是对问题空间的抽象,而类模板则是对类的抽 象,即更高层次上的抽象。与函数模板相似,程 序中可以通过高度抽象首先定义一个模板类,然 后通过使用不同的实参生成不同类的对象
Person Wang;
{
strcpy(m_strDept, dept); cout<<"constructor of Employee"<<endl; } ~Employee() { cout<<"deconstrucor of Employee"<<endl; } };
派生类构造函数的执行次序
保护继承(public)
保护继承方式创建的派生类对基类各种成员访问 权限如下 :
基类的公有成员和保护成员都相当于派生类的 保护成员,派生类可以通过自身的成员函数或 其子类的成员函数访问他们 对于基类的私有成员,无论派生类内部成员或 派生类使用者都无法直接访问
8.3 派生类的构造函数和析构函数
Employee(){}
void SetDepartment(const char *); void SetSalary(float); char *GetPosition() const; float GetSalary() const; ... ... };
char GetSex();
例8-2 人员类(Person)的私有派生类
例8-3
{
派生类构造函数和析构函数的执行
class Person
char int m_strName[10]; m_nAge;
public:
Person(char* name,int age) { strcpy(m_strName, name);
m_nAge = age;
cout<<"constructor of person"<<m_strName<<endl; } ~Person() { cout<<"deconstrutor of person"<<m_strName<<endl;} };
public:
void GetName(char *Name); int ... ... }; GetAge(); char GetSex();
void SetSalary(float);
char *GetPosition() const; float GetSalary() const; ... ... };
class Employee:private Person
{char m_sDepartment[21];
char m_sPosition[21]; float m_fSalary; public:
int
public: void int ... ... };
m_nSex;
GetName(char *Name); GetAge();
新增私有数据成员和成员函数
protected: 新增保护数据成员和成员函效
public:
新增公有数据成员和成员函效 }
派生类中的变化
派生类对基类的扩充
派生类对基类成员的改造
系统的默认值就是私有继承(private)。
8.2 派生类的继承方式
私有继承pBiblioteka ivate公有继承public
保护继承protected
实例:公有继承(public)
class Person { private: char m_strName[20]; int int m_nAge; m_nSex;
class Employee:public Person {char m_sDepartment[21]; char m_sPosition[21]; float m_fSalary; public: Employee(){} void SetDepartment(const char *);
私有继承 (private)
派生类对基类各种成员访问权限如下 :
基类公有成员和保护成员都相当于派生类的私 有成员,派生类只能通过自身的函数成员访问 他们 对于基类的私有成员,无论派生类内部成员或 派生类使用者都无法直接访问。
实例:私有继承(private)
class Person { private: char int m_strName[20]; m_nAge;
// 路
// 行 // 是否显示 // 是否被选择
void MoveTo(int col, int row) { m_nCol=col, m_nRow=row; } void KillIt() { m_bShow = false; } void Select() { m_Selected = !m_Selected; }
例8-3
{
派生类构造函数和析构函数的执行
class Employee : public Person char public: Employee(char *name, int age, char *dept, char *name1, int age1) : Person(name,age) , Wang(name1,age1) m_strDept[20];
首先,调用基类构造函数,调用顺序按照它们被 继承时声明的基类名顺序执行。 其次,调用内嵌对象构造函数,调用次序按各个 对象在派生类内声明的顺序。 最后,执行派生类构造函数体中的内容。
析构函数
派生类析构函数执行过程恰与构造函数执行过程 相反。 首先执行派生类析构函数 然后执行内嵌对象的析构函数 最后执行基类析构函数
一个基类有多个派生类
class Person
{ protected:
char m_strName[10];
int m_nSex; int m_nAge;
public:
void Register(char *name,int age,char sex); void ShowMe();
};
例8.5
一个基类有多个派生类
例8-6 定义一个棋子类,再定义一个棋子类的派 生类—象棋子类,并写出测试主函数。
class Stone {protected: int m_nColor; // 颜色
int m_nCol;
int m_nRow; bool m_bShow; bool m_Selected; public: Stone(int color, int col, int row);
class Teacher : public Person { char m_strDept[20]; int m_fSalary; public: Teacher(char *name,int age,char sex,char *dept,int salary); void ShowMe(); };
8.4 显式访问基类成员 8.5 静态成员
8.6 类模板
调试技术 程序设计举例
8.1 继承和派生
派生类的定义格式为:
class 派生类名:继承方式 基类名1,继承方式 基类 名2,…,继承方式 基类名n
{
派生类增加的成员声明; };
图8.1 水果的分类
派生类的语法结构
class <派生类名>:<访问权限> <基类名> { private:
class Employee: private Person { char m_strDept[20]; float m_fSalary; public: Employee()