C++第08章+继承与派生
c 程序设计基础-第八章-继承和派生
例2-图形类及其派生类的声明
class Circle : public Shape { public:
Circle(int x, int y, float r=1, char color='R'); void SetCircle(int x, int y, float r, char color); float GetRadius () const; void Draw(); private: float m_Radius; };
3. 读取属性值
13
8.2.2 定义派生类
派生类的定义格式
class 派生类名:继承方式 基类名 {
public: //派生类公有成员… private: //派生类私有成员… }
派生类只有 一个直接基 类为单继承
14
8.2.2 定义派生类
class 派生类名:继承方式 基类名1, … 继承方式 基类名n
shape
• 色彩 color • 位置 (x, y)
circle rectangle
triangle
10
8.2.1 简单的继承和派生
图形
circle 圆形 rectangle 矩形 triangle 三角形
shape
分层次的设计类使模块划分更合
理;便于软件系统的设计和维护。
基类称为父类 派生类称为子类
21
例2-图形类及其派生类的声明
class Rectangle: public Shape { public:
Rectangle(int x, int y, char color, int length=10, int width=10); void SetRectangle (int x, int y, char color, int length, int width); int GetWidth() const; int GetHeight() const; void Draw(); private: int m_Width; int m_Length; };
C继承和派生
C继承和派生简单来说:有两个类A和B,A是父类,B是子类。
那么就可以说:A派生出B,B继承与A。
例:父亲“派生” 出儿子儿子“继承” 自父亲派生和继承,本质是相同的,只是从不同角度来描述他们而已。
继承和派生在UML中的表示:注意是空心三角形从子类【派生的类】指向父类【被继承的类】父类,也被称为”基类”除了”构造函数“ 和”析构函数“,父类的所有成员函数,以及数据成员,都会被子类继承!假如已经定义好了父类Father,里面定义好私有数据成员name 和age,和公有的构造函数、成员方法description等。
当子类Son 要继承父类Father时,需要包含”父类的头文件“,定义方式如下:公有继承方式#include "Father.h" // 包含父类的头文件class Son : public Father {// 详细见下面全部代码}假如子类Son要调用自定义的重载构造函数是:1.会先调用父类的构造函数,用来初始化父类继承的数据,2.再掉用自己的构造函数,用来初始化自己定义的数据。
例:Son::Son(const char *name, int age, const char *game) : Father(name, age) {// 没有体现父类的构造函数, 那就会自动调用父类的默认构造函数this->game = game; // 子类自己定义的数据成员}注意一:子类的成员函数,不能访问从父类继承的private成员例:在子类Son中,this->name = name;或者cout << age << endl;都是错误的。
但子类可以访问父类的成员函数,如cout << getName() << getAge() << endl;都是正确的。
注意二:子类对象调用方法时,现在自己定义的方法中去寻找,如果有,就调用自己定义的方法;如果找不到,就到父类的方法中去找,如果有,就调用父类的这个同名方法;如果在父类中找不到,就发生错误!例:父类和子类都定义了description方法,子类Son去调用这个方法,会优先在自己的方法里去找来调用,如果没有,再去父类里找;也没有的话就报错。
继承与派生类答案
继承与派生类知识要点1.掌握继承和派生的定义,派生类的定义方法。
(1)掌握继承的两种类型:单继承和多继承。
(2)掌握private,public,protected三种继承方式的特点。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private成员在派生类中不可见。
区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3)掌握派生类中的构造函数和析构函数的使用。
基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。
派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4)掌握派生类的同名覆盖规则。
(5)掌握赋值兼容规则。
基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2.掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。
派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3.掌握虚基类的概念和定义方法。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
总结-----c 之继承和派生
继承和派生一.继承(inheritance):在一个已存在的类的基础上建立一个新的类。
在c++中可重用性是通过继承这一机制实现的。
派生(derived):在已有类的基础上新增自己的特性而产生新类的过程。
共享基类的成员。
派生类不会继承基类的友元关系。
派生类同时也是一个组合:创建一个新类,类中的一个或者多个对象是其他类的成员。
被继承的类称为基类(base class),派生出的类称为派生类(derived class)。
一个派生类可以从一个基类派生,称之为单继承。
也可以从多个基类派生,称之为多继承。
派生过程基类不会作出改变。
派生类则除了继承基类所有可引用的成员外,还可以另外定义新的成员。
继承首先是代码重用的一种机制,但另一个重要的特性在于:继承描述了一组类,这组类在一个相关联的层次上,一个类可以看作是另一个类。
二.继承的目的:实现代码重用。
通过继承机制,可以利用已有的数据类型来定义新的数据类型。
派生的目的:当新的问题出现,原有程序无法解决时,对原有程序进行改造。
三.派生类的声明Class 派生类名:继承方式基类名{派生类新增加的成员声明;}派生类一部分是从基类继承的成员,一部分是在声明派生类时新增加的部分。
四.派生生成过程。
1.吸收基类成员:吸收除构造函数和析构函数外的数据。
2.改造基类成员:声明一个和基类成员同名的新成员,派生类中的新成员就屏蔽了基类同名成员称之为同名覆盖。
这里的屏蔽或者覆盖并不是真正意义上的覆盖,依然可以通过基类名加作用域操作符(::)进行访问。
3.发展新成员:派生类新增加的成员。
新增加的成员需与基类成员不同命。
4.重写构造函数和析构函数:被重新定义的基类函数是虚函数,则称派生类中同名函数为重写。
派生类不会继承基类的构造函数和析构函数。
五.继承方式:继承方式不同影响派生类成员对基类成员访问权限。
1.Pubulic access(公有继承):派生类继承基类的public和protected 且访问属性不变。
C++面向对象程序设计第八章继承与派生
13
8.4
派生类的构造函数与析构函数
在产生新的对象时, 都会调用相应的构造函数。 构造函数的作用有两点: (1)为成员变量分配存储空间。 (2)初始化成员变量的值。 派生类的构造函数? 析构函数? 基类的构造函数和析构函数是不能被继承的!
14
8.4.1简单派生类的构造函数
25
8.7继承与组合
在实际的程序开发过程中,使用面向对象的方 法,在建立新类的时候,要弄清新类与已有类 之间的关系 看究竟是 看究竟是ISA关系还是HASA关系? 关系还是 关系? 如果是ISA关系,就要通过继承来产生新的类 如果是HASA关系,就要通过组合来产生新的类
【例8.14】继承与组合示例 】
21
8.5.3多重继承的问题 【例8.10】 多重继承的问题 】
解决的办法之一:在处理变量时通过 基类名加上域作用符的方式 指明要操作的究竟是哪个变量 这样即不符合现实,还浪费了存储空间 解决的办法之二: 采用 虚基类
22
8.5.4虚基类
在继承时通过关键字virtual声明为虚继承, 相应的基类就成了虚基类。
6
8.2
派生类的声明方式及构成
比较这个定义和上一节中给出的undergraduate 定义,很容易发现继承的写法: 默认为private私 默认为 私
有继承 基类名1, 基类名2, class 子类名 : 继承方式 基类名 ,继承方式 基类名 , [继承方式] 父类名 …继承方式 基类名 继承方式 基类名n { 继承方式可以是 public(公有继承) (公有继承) 类的定义体 private(私有继承) (私有继承) protected(保护继承) (保护继承) };
C 继承与派生分解
X=x; Y=y;
派生类中的 成员函数 可以直接访 问基类中的public和protected成 员,但不能访问基类的private成 员。
2. 私有继承
基类
派生类成员 函数可以访问
派生类 基类 private 成员的 属性
public: protected: private: 派生类对象
private ? private ? private ?
};
class Point { public: void InitP( float xx=0, float yy=0 ) {X=xx; Y=yy;} void Move( float xOff, float yOff ) {X+=xOff; Y+=yOff;} float GetX( ) {return X;} float GetY( ) {return Y;} private: ??? float X,Y; }; 1. 2. 3. 4. 5. 6. int main( ) { Rect r(1, 2, 3, 4); cout<<r.X; cout<<r.GetX( ); return 0; }
派生类新成员定义;
};
class Point {//基类 public: void InitP(float xx=0, float yy=0) {X=xx; Y=yy;} void Move(float xOff, float yOff) {X+=xOff; Y+=yOff;} float GetX() {return X;} float GetY() {return Y;} private: float X,Y; }; int main( ) { Rectangle rect; cout<<rect.X; //可否? cout<<rect.GetX( ); //可否? return 0; }
C类的继承和派生ppt课件
cout<<"("<<x<<","<<y<<")"<<en dl; }
-
//Circle.h文件 #ifndef CIRCLE_H #define CIRCLE_H #include <iostream> #include "Point.h" using namespace std; class Circle:public Point { protected:
name=nam; sex=s; } ~Student( ){ } protected: int num; string name; char sex ; };
-
class Student1: public Student { public:
Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)
using namespace
std;
{ protected:
class Base
int j;
{ protected:
int i; public:
void F()
public: void Fun() { i=20; }
};
{
void main()
} };
{ Drived d;
}
-
4.5 派生类的构造函数和析构函数
如程序PointRect1所示:
-
4.4继承方式
最新《c 程序设计基础》第八章-继承和派生
❖ 方法二:面向对象?
▪ class circle 圆形
泛 ▪ class rectangle 矩形 化 ▪ class triangle 三角形 ? ▪ 基类: class shape
shape
• 色彩 color • 位置 (x, y)
circle rectangle
triangle
10
8.2.1 简单的继承和派生
class Shape: { public:
Shape(int x=0, int y=0, char c = 'R'); int GetX() const; void SetX( int x); int GetY() const; void SetY( int x); char GetColor() const; void SetColor(char c); protected: char m_color; int m_x; int m_y; };
17
class base {…… }; class deriver1:public base { …… }; class deriver2:public deriver1 {…… }
8.2.2 定义派生类
• 父类被称为子类的直 接基类
• 父类的父类或更高层 次的父类被称为这个 子类的间接基类
18
例2-图形类及其派生类的声明
的访问权限。 ❖ 每一个“继承方式”,只用于限制对紧随其后之基类的继承。
class derive : public b1 , private b2 { private:
int newInt; public:
void newFun(); private:
int max( int a, int b ); };
08第八章继承与派生
私有基类成员 私有成员 公有成员 保护成员来自在派生类中的访问 属性
不可访问 私有 私有
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语言程序设计基础-实验八继承与派生类
实验八继承与派生类1.实验目的要求(1)掌握单继承程序设计的基本方法。
(2)掌握多继承程序设计的基本方法。
2.实验设备电脑一台,Microsoft Visual C++ 6.03.实验内容(1) 下面程序定义一个vehicle类,并派生出car和truck两个派生类。
#include<iostream.h>class vehicle{protected:int wheels;double weight;public:void initialize(int whls, double wght);int get_wheels() { return wheels; }double get_weight() { return weight; }double wheel_loading() { return weight/wheels; } };class car: public vehicleprivate:int passenger_load;public:void initialize(int whls, double wght, int people =4);int passengers() { return passenger_load; }};class truck: public vehicle{private:int passenger_load;double payload;public:void init_truck(int number =2, double max_load =24000.0);double efficiency();int passengers() { return passenger_load; }};void vehicle::initialize(int whls, double wght){wheels=whls;weight=wght;}void car::initialize(int whls, double wght, int people){wheels=whls;weight=wght;passenger_load=people;void truck::init_truck(int number, double max_load){passenger_load=number;payload=max_load;}double truck::efficiency(){return payload/(payload+weight);}void main(){vehicle bicycle;bicycle.initialize(2,25);cout<<"the bicycle has "<<bicycle.get_wheels()<<" wheels.\n";cout<<"the bicycle weighs "<<bicycle.get_weight()<<" pounds.\n";cout<<"the bicycle's wheel loading is "<<bicycle.wheel_loading()<<" pounds per tire.\n\n";car audi;audi.initialize(4,3500.0,5);cout<<"the audi has "<<audi.get_wheels()<<" wheels.\n";cout<<"the audi weighs "<<audi.get_weight()<<" pounds.\n";cout<<"the audi's wheel loading is "<<audi.wheel_loading()<<" pounds per tire.\n\n";truck jief;jief.initialize(18,12500.0);person person teacher graduate in-service_graduatejief.init_truck(2,33675.0);cout<<"the jief has "<<jief.get_wheels()<<" wheels.\n";cout<<"the jief weighs "<<jief.get_weight()<<" pounds.\n";cout<<"the jief's efficiency is "<<100.0*jief.efficiency()<<" percent.\n";}[基本要求]● 上机录入、调试上面程序。
C++继承与派生
8
8.2.3 派生类对象的初始化和撤销
1.派生类对象的初始化 在派生类对象中包含一个匿名的基类对象,在创建和初始化派生类对象 时,系统按照一定的顺序进行:先初始化该匿名的基类对象,然后再初始化派生 类自己的新增成员。 匿名基类对象的初始化由基类的构造函数来完成,派生类的构造函数会 调用基类的构造函数来完成匿名基类对象的初始化,默认情况是调用基类无参数 的构造函数,如果要调用其他带参数的构造函数,则必须在派生类构造函数的成 员初始化列表中指出。派生类构造函数的一般格式为:
name offertel dept no sal specialty一
Programmer类对象内存影像
5
8.2.2 继承方式以及派生类成员的访问
从基类继承的成员也可能会在两个地方被访问:①在派生类内部,派 生类新增的函数可能会访问从基类继承的成员。②在派生类的外部,通过派生 类对象来访问从基类继承的成员。对从基类中继承的成员的访问,受到其在派 生类中的访问控制方式的限制,而基类的成员在派生类中的访问权限由该成员 在基类中的访问控制方式和派生类的继承方式共同决定的。 继承方式在定义派生类时指出,如未指出,则默认为private。继承方 式对基类成员在派生类中的访问控制方式的影响如表所示。
A B
C 图8-5 多级继承关系
Байду номын сангаас
13
8.3 多重继承
14
8.3.1 多重继承的定义
在定义多重继承的派生类时,需要给出两个或两个以上的直接基类,其格式为: class <派生类名>:[<继承方式>]<基类名>,[<继承方式>]<基类名>,......{ <派生类新增成员说明表> }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10
第八章 继承与派生
基类成员在派生类中的存取权限
(1) 无论何种派生方式,基类的私有成员在派生类中不 能访问;基类的保护成员和公有成员在派生类内部可进 行存取。 (2) 私有派生使基类的保护成员和公有成员都成为派生 类的私有成员,在派生类中可直接访问,在类外不能访 问。一般情况下,私有派生使用较少,它中止了基类功 能的进一步派生。 (3) 保护派生使基类的保护成员和公有成员都成为派生 类的保护成员,在派生类中可直接访问,在类外不能访 问。它与私有派生的不同表现在进一步派生时。 (4) 公有派生使基类的保护成员和公有成员在派生类中 不变,仍然是保护成员和公有成员。在类外可访问公有 11 成员,不可访问保护成员。
26
第八章 继承与派生
3. 赋值兼容规则 派生类对象间的赋值操作依据下面的原则: (1) 如果派生类有自己的赋值运算符的重载定义, 即按该重载函数处理。 (2) 派生类未定义自己的赋值操作,而基类定义了 赋值操作,则系统自动定义派生类赋值操作,其中 基类成员的赋值按基类的赋值操作进行。 (3) 二者都未定义专门的赋值操作,系统自动定义 缺省赋值操作。
生类继承的成员仍是某类的友元。
25
第八章 继承与派生
2. 静态成员的继承 如果基类的静态成员是公有的或是保护的,则 它们被其派生类继承为派生类的静态成员。即: (1) 这些成员通常用<类名>::<成员名>方式引 用或调用(在派生类的访问属性为public时)。 (2) 这些成员无论有多少个对象被创建,都只有一 个拷贝。它为基类和派生类的所有对象共享。
13
第八章 继承与派生
例:
雇员
兼职技术人员
管理人员
销售人员
销售经理
单一继承:一个派生类只有一个直接基类 多重继承:一个派生类可以同时有多个基类 多级继承:派生类又派生出派生类
14
第八章 继承与派生
多重继承举例: class A{ public: void setA(int); void showA( ); private: int a; }; class B{ public: void setB(int); void showB( ); private: int b; }; class C : public A, private B { public: void setC(int, int, int); void showC( ); private: int c; 15 };
employee
manager director engineer
3
第八章 继承与派生
• 保持已有类的特性而构造新类的过程称为继承。 • 在已有类的基础上新增自己的特性而产生新类 的过程称为派生。 • 被继承的已有类称为基类(或父类)。 • 派生出的新类称为派生类(或子类)。 • 基类与派生类是相对而言的。 • 直接参与派生出某类的基类称为直接基类。 • 基类的基类或更高层的基类称为间接基类(祖先 类 )。
例:阅读程序p8_4.cpp,观察其运行结果
29
第八章 继承与派生
8. 4 派生关系中二义性处理
同名覆盖原则:
当派生类与基类中有相同成员时: • 若未强行指名,则通过派生类对象使 用的是派生类中的同名成员。 • 如要通过派生类对象访问基类中被覆 盖的同名成员,应使用基类名限定(::)。
30
第八章 继承与派生
(3) 最后调用基类的析构函数。
23
第八章 继承与派生
例:派生类的构造函数和析构函数举例: P8_3.cpp 课本P260 program8_3.cpp 阅读程序并分析输出结果
24
第八章 继承与派生
8.3 其它特征的继承关系
1. 友元关系的继承
(1)基类的友元不继承。即:基类的友元不一定是 派生类的友元,除非特别声明; (2)若基类是某类的友元,则这种友元关系是被继 承的,即若基类的成员是某类的友元,则其作为派
27
第八章 继承与派生
另一方面,基类对象和派生类对象之间允许有赋值关系:
• 一个公有派生类的对象在使用上可以被当 作基类的对象,反之则禁止。具体表现在: – 派生类的对象可以被赋值给基类对象。 – 派生类的对象可以初始化基类的引用。 – 指向基类的指针也可以指向派生类。
但是:通过这个基类的对象(或引用、指针)只能访问 到基类的成员,不能访问到派生类的新增成员。
4
第八章 继承与派生
• 继承的目的:实现代码重用。 • 派生的目的:当新的问题出现,原有
程序无法解决(或不能完全解决)时,
需要对原有程序进行改造。
5
第八章 继承与派生
8.2 派生类说明及其构造函数和析构函数
8.2.1 派生类说明
class 派生类名:继承方式1 基类名1, 继承方式2 基类名2,... { 派生类新增成员声明; };
第八章 继承与派生
派生类的构造函数的一般格式如下: <派生类名>(<参数总表>):<初始化列表> { <构造函数体> } 而 <初始化列表> 按如下格式构成:
< 基 类 名 1>(< 基 类 参 数 表 1>) , ... , < 基 类 名 n>(<基类参数表 n>),<对象成员名1>(<对象成员参数 表1>), ... ,<对象成员名m>(<对象成员参数表m>)
17
第八章 继承与派生
在派生类中,成员按访问属性划分为四种:
1) 不可访问的成员 -- 基类的 private 私有成员被 继承过来后,这些成员在派生类内外均不可访问。 2) 私有成员 -- 包括在派生类中新增加的 private 私有成员以及从基类私有继承过来的公有和保护成员。 这些成员在派生类内可以访问,派生类对象不可访问。 3)保护成员 -- 包括在派生类中新增加的 potected 保护成员以及从基类继承过来的某些成员。这些成员在 派生类内是可以访问的,派生类对象不可访问。 4)公有成员 -- 包括在派生类中新增加的 public 公 有成员以及从基类公有继承过来的公有成员。这些成员 不仅在派生类中可以访问,而且派生类对象也可以访问 它们。 18
注意:每一个“继承方式”(又叫派生方式), 只用于限制对紧随其后之基类的继承。
6
第八章 继承与派生
例如: class B0{…………..};//基类B0 class B1{…………..};//基类B1 class B2{…………..};//基类B2
class C : public B0, private B1,protected B2 { public: void setC(int, int, int); void showC( ); private: int c; };//派生类C
二义性处理方法: 1.单继承时父类与子类 间同名成员的处理 单继承时父类与子 类间成员重名时,按如 下规定进行处理:对子 类而言,不加类名限定 时默认为是处理子类成 员,而要访问父类重名 成员时,则要通过类名 限定。 C类的结构 B类 int i void fun() C类 int i
28
第八章 继承与派生
例如 设:类CB 是类CD 的基类 CB CBobj,*pcb; CD CDobj; 则:
允许派生类对象赋值给基类对象:CBobj=CDobj; 允许指向基类对象的指针=派生类对象的地址: pcb=&CDobj; 允许派生类对象为基类的引用型对象赋初值: CB &CBref=CDobj;
7
第八章 继承与派生
派生类的生成过程 1) 吸收基类成员
派生类接受了基类中除构造函数和析构函数 外的所有成员。
2) 改造基类成员
按照继承方式改变继承而来的基类成员的访问 属性
3) 添加新成员
给派生类增加适当的数据和函数成员以实现新
的功能。
8
第八章 继承与派生
派生类成员的构成
派 生 类
继 承 部 分 新 增 加 部 分
第八章 继承与派生
例1:公有继承举例见p8_1
例2:私有继承举例见p8_2
12
第八章 继承与派生
相关概念与注意事项:
(1) 一个类可以派生出多个派生类。 (2) 一个类可有一个或多个基类,称为单一继承和多 重继承。 (3) 派生类又可有派生类,称为多级继承。 (4) 继承关系不可循环。例如,类A 继承类B,类B 继承类C,类C 又继承类A,这是非法的。 (5) 基类的友元关系、基类的构造函数和析构函数都 不能被派生类所继承。
私有成员
保护成员 公有成员 私有成员 保护成员 公有成员
9
第八章 继承与派生
继承方式(派生方式) • 三种继承方式 – 公有继承(public) – 私有继承(private) – 保护继承(protected) • 不同继承方式的影响主要体现在: 1、派生类成员对基类成员的访问控制。 (即基类成员在派生类内部的存取权限) 2、派生类对象对基类成员的访问控制。 (即基类成员在派生类外部的访问控制)
21
第八章 继承与派生
派生类构造函数执行的一般次序如下: (1) 调用各基类的构造函数,调用顺序按继承时 的声明顺序,从左到右。 (2) 若派生类含有对象成员的话,调用各对象成 员的构造函数,调用顺序按照定义顺序。 (3) 执行派生类构造函数的函数体。
22
第八章 继承与派生
派生类的析构函数 派生类的析构函数的定义方法与没有继承关 系的类中析构函数的定义方法相同,只要在函数 体中负责把本派生类新增的非对象成员的清理工 作做好就够了,系统会自己调用基类及对象成员 的析构函数。但各析构函数的调用顺序正好与构 造函数的调用顺序相反。即: (1) 先调用派生类自己的析构函数; (2) 再调用对象成员的析构函数;