继承与派生的基本概念
继承与派生
4.1 继承和派生的概念
在软件开发过程中,在定义特殊类时,不需把它的一 般类已经定义过的属性和服务重复地书写一遍,只需要声 明它是某个类的特殊类,并定义它自己的特殊属性和服务。 这将明显地减轻开发工作的强度。 4.1.2 继承的作用 面向对象程序设计的继承性使得大型应用程序的维护 和设计变得更加简单。一方面,大型应用程序设计完成并 交付使用后,经常面临用户的需求发生变化,程序功能需 要扩充等问题。这时程序的修改需要非常谨慎,因为某个 局部的修改可能会影响其他部分,而一个正在使用中的系 统要进行全面的测试,既费时间又有很多实际的困难。另 一方面,一个新的应用系统程序设计在许多方面会和以前 设计过的某个或某些系统的模块非常类似,怎样加快大型 应用程序的开发速度,重用这些已经开发成功的程序模块, 一直是软件设计中迫切需要解决的问题。
4.2 派生类
C++语言派生类多重继承的定义格式如下: class <派生类名>:[继承方式1] [<基类名1>],[继承 方式2] [<基类名2>],…, [继承方式n] [<基类名n>] { <派生类成员变量和成员函数定义> }; 通常,在多重继承时,继承方式设计成一致的形式。 如继承方式均设计成public,或均设计成private。
7章_继承与派生
例1 void main() class A{ { A a; protected: B b; int X; b.Function(); }; a.X=5; class B:public A b.X=7; { } public: 错误,水平访问时 void Function(); 保护成员相当于 }; 私有成员 void B::Function() { 正确,垂直访问时 X=5; 保护成员相当于 }
例(续2)
#include <iostream> using namespace std; void main( ) { Rectangle rect; rect.InitR(2,3,20,10); //水平访问 rect.Move(3,2); // 直接调用基类公有成员函数 cout<<rect.GetX()<<","<<rect.GetY()<<"," <<rect.GetH()<<", "<<rect.GetW()<<endl; } 输出: 5,5,10,20
公有成员
例7_1:分析下列程序中的访问权限
class Point { public: void InitP(int xx,int yy); void Move(int xOff,int yOff); int GetX() {return X;} int GetY() {return Y;} private: int X,Y; }; //基类声明结束 void Point::InitP(int xx,int yy) //函数成员实现 { X=xx; Y=yy; } void Point::Move(int xOff,int yOff) { X+=xOff; Y+=yOff; }
1. 继承与派生的概念。
1. 继承与派生的概念。
1. 继承的概念:继承是面向对象编程中的一个重要概念,它允许我们创建新的类,通过继承现有类的属性和方法来实现代码的重用。
在继承中,有两个类之间的关系,一个是称为父类或基类的类,另一个是称为子类或派生类的类。
子类继承了父类的属性和方法,并且可以根据需要添加自己的额外属性和方法。
继承的概念可以通过一个简单的例子来说明。
假设我们有一个父类叫做An i m a l,它有一个属性n a m e和一个方法s p e a k。
然后我们创建一个子类叫做C a t,它继承了A n i m a l类的属性和方法,并且可以添加自己的额外属性和方法。
通过继承,C a t类可以访问和使用A n i m a l类的属性和方法,同时也可以根据需要添加新的行为。
2.派生的概念:派生是指在继承的过程中创建子类的过程。
通过派生,我们可以基于父类创建新的子类,并且在子类中添加新的属性和方法来实现代码的扩展和重用。
派生可以看作是继承的一种具体实现方式。
派生的概念可以通过继续上面的例子来说明。
假设我们有一个C a t类作为子类,它继承了A n i m a l类作为父类。
在C at类中,我们可以添加额外的属性和方法,如c o l o r和c a t c h M o u s e。
通过派生,C a t类可以获得An i m a l类的属性和方法,并且可以根据需要添加自己的新行为。
3.继承与派生的关系:继承和派生是紧密相关的概念。
继承是指子类从父类继承属性和方法的过程,以实现代码的重用。
而派生是指在继承的过程中创建子类,并且在子类中添加新的属性和方法的过程,以实现代码的扩展。
继承和派生的关系可以通过一个更复杂的例子来说明。
假设我们有一个基类叫做S h a p e,它有一个属性co l o r和一个方法d r a w。
然后我们创建两个子类,一个是C i r c l e,另一个是R e c t a n g l e,它们分别继承了S h a p e类,并且可以根据需要添加自己的额外属性和方法。
《继承与派生 》课件
目录
CONTENTS
• 继承与派生的基本概念 • 继承的方式 • 派生类的构造函数和析构函数 • 继承与多态 • 继承与重载
01
继承与派生的基本 概念
继承的定义
继承是面向对象编程中的一个重 要概念,它允许一个类(子类) 继承另一个类(父类)的属性和
方法。
通过继承,子类可以复用父类的 代码,减少代码冗余,提高代码
保护继承
总结词
保护继承是指基类的保护成员在派生类 中保持保护属性,可以被派生类和派生 类的对象访问。
VS
详细描述
保护继承时,基类的保护成员在派生类中 保持保护属性,可以被派生类和派生类的 对象访问。这种继承方式使得基类的保护 成员成为派生类的保护成员,可以被派生 类和派生类的对象访问。因此,派生类可 以继承基类的保护成员函数和变量。
03
派生类的构造函数 和析构函数
派生类的构造函数
派生类构造函数的作用
派生类构造函数用于初始化派生类对象,包括调用基类构造函数 和执行派生类特有的初始化操作。
派生类构造函数的执行顺序
派生类构造函数的执行顺序是在创建派生类对象时,先调用基类构 造函数,然后执行派生类构造函数体中的代码。
派生类构造函数的参数
继承和派生共同实现 了面向对象编程中的 代码复用和多态性。
派生是继承的一种表 现形式,通过派生可 以创建新的类。
02
继承的方式
公有继承
总结词
公有继承是ቤተ መጻሕፍቲ ባይዱ基类的公有成员在派生类中仍为公有成员,可以被派生类和派生类的对象访问。
详细描述
公有继承时,基类的公有成员在派生类中保持公有属性,派生类可以访问基类的公有和保护成员。这种继承方式 使得基类的公有成员成为派生类的公有成员,可以被派生类和派生类的对象直接访问,因此派生类可以继承基类 的公有成员函数和变量。
继承与派生
§5 派生类的构造函数和析构函数
构造函数的主要作用是对数据成员初始化, 构造函数的主要作用是对数据成员初始化, 所以在设计派生类的构造函数时,不仅要考 所以在设计派生类的构造函数时, 虑派生类所增加的数据成员的初始化, 虑派生类所增加的数据成员的初始化,还应 当考虑基类的数据成员的初始化。 当考虑基类的数据成员的初始化。在执行派 生类的构造函数时, 生类的构造函数时,调用基类的构造函数
一、简单的派生类的构造函数
1、概念 、 任何派生类都包含基类的成员, 任何派生类都包含基类的成员,简单的派生类只 有一个基类,而且只有一级派生(只有直接派生类 有一个基类,而且只有一级派生 只有直接派生类 没有间接派生类), ,没有间接派生类 ,在派生类的数据成员中不包 含基类的对象(即子对象 即子对象)。 含基类的对象 即子对象 。 2、其一般形式为: 、其一般形式为: 派生类构造函数名(总参数表列) 派生类构造函数名(总参数表列): 基类构造 函数名(参数表列) 函数名(参数表列) {派生类中新增数据成员初始化语句 派生类中新增数据成员初始化语句} 派生类中新增数据成员初始化语句
二、私有继承
2、私有基类在派生类中的访问属性 、 私有基类的成员 在私有派生类中的访问属性 私有成员 不可访问 公用成员 私有 私有 保护成员 3、例11.2 、
三、保护成员和保护继承
1、概念 、 声明的成员称为“ 由protected声明的成员称为“受保护的成员”, 声明的成员称为 受保护的成员” 或简称“保护成员” 或简称“保护成员”,保护成员可以被派生类的 成员函数引用
第十二章 继承与派生
§1 继承与派生的概念
继承: 继承:是在一个已存在的类的基础上建立一个新 的类,已存在的类称为“基类” 父类” 的类,已存在的类称为“基类”或“父类”。新 建立的类称为“派生类” 子类” 建立的类称为“派生类”或“子类”。 一个新类从已有的类那里获得其已有特性, 一个新类从已有的类那里获得其已有特性,这种 现象称为类的继承 从已有的类(父类 类的继承。 父类)产生一个新 现象称为类的继承。从已有的类 父类 产生一个新 的子类,称为类的派生 类的派生。 的子类,称为类的派生。 单继承: 单继承:一个派生类只从一个基类派生 多继承: 多继承:一个派生类有两个或多个基类 派生类是基类的具体化, 派生类是基类的具体化,而基类则是派生类的抽象
第7章 继承和派生
例:7.3分析下列程序的结果:
class Base1 { public: Base1(int i ) { b1=i ; cout<<"Constructor of Base1."<<endl; }
void Print() const
private:
{ cout<<b1<<endl; }
int b1;
Member ( int i)
{ m=i ; cout<<"Constructor of Member."<<endl; } int GetM ( ) { return m; } private: int m; };
16
class Derived : public Base2, public Base1 ,public Base3
{ b1=i;
b2=j;
cout<<"Base's constructor called."<<b1<<","<<b2<<","<<endl;
} Base::~Base ( ) {cout<<"Base's }
destructor called."<<b1<<","<<b2<<","<<endl;
23
Base's destructor called.1,2,
27
§7.4多继承与虚基类
§7.4.1多继承中的二义性问题 产生二义性问题主要有两种情况: ㈠产生二义性问题的第一种情况如下例: 如P215图7.4(a) class Base1 { public: void fun(); };
第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应该 所以作为访问控制权限的 应该 出现在基类中而不一定出现在派生类中。 出现在基类中而不一定出现在派生类中。
C _4_继承和派生
第四章继承和派生§4—1 继承§4—2 单继承§4—3多继承§4—1 继承一、继承的含义①面向对象方法提供了从问题域到解域的自然映射客观世界中的对象既有共性,也有个性,通过不同程度的抽象,形成了分类和层次结构不同层次的类之间体现了概括(generalize)和特化(specify)关系把高层次的类称为父类、超类和基类,把由该类特化产生的低层次类称为子类或派生类派生类不仅具有基类的属性和行为,还具有自己特有的属性和行为②在不同类之间,除了概括和特化的关系外,还有聚合和分解关系模块化的主要目的是实现软件的可复用性从模块的角度看,继承是一种关键性的复用技术③继承机制提供了一种充分利用现有资源的方法它既体现了经济思想,又体现了谦虚精神:我比别人看得远,是因我站在巨人的肩上——牛顿继承使得在创建新类时,只需说明新类与基类的区别,从而大量原有代码都可复用④派生类是基类的具体化,是基类定义的延续在多继承时,派生类也是基类的组合二、继承的概念1.基类即父类,超类,是已存在的用来派生新类的类,是被继承的类2.派生类即子类,是由己存在的类派生出的新类,是继承其他类特性的类3.单继承即单重继承,每个派生类只有一个直接父类是从一个基类派生的继承,形成类的层次,像一棵树4.多继承即多重继承,派生类可以有多个直接父类是从多个基类派生的继承,形成一个有向无环图(DAG图)5.类的层次结构直接基类、间接基类、直接派生类、间接派生类多层继承:一个基类可以是另一个基类的派生类区别:多层继承和多重继承三、派生类的定义①单继承class 派生类名: 继承方式基类名{派生类新定义成员;};②多继承class 派生类名: 继承方式1 基类名1,继承方式2 基类名2,……{派生类新定义成员;};四、继承方式共有三种:公有继承:public保护继承:protected私有继承:private 可缺省继承方式基类特性派生类特性公有继承public publicprotectedprivatepublicprotected不可访问或不可见保护继承public protectedprotected protectedprivate protected 不可访问私有继承(缺省)private publicprotectedprivateprivateprivate不可访问派生类不能继承基类的构造函数、析构函数和友元1.基类的私有成员只能被基类中的成员函数和友元函数访问,不能被其他函数访问2.基类的保护成员只能被基类及其派生类中的成员函数和友元函数访问3.公有继承派生类的对象可以访问基类中的公有成员派生类的成员函数可以访问基类中的公有成员和保护成员4.保护继承和私有继承派生类的对象不能访问基类中的任何成员派生类的成员函数可以访问基类中的公有和保护成员5.私有继承基类的公有和保护成员只能由直接派生类访问,无法再往下继承§4—2 单继承每个派生类只有一个直接基类,但每个基类可以有多个派生类一、成员访问权限的控制二、成员访问权限的调整①保护继承和私有继承将改变基类的公有和保护成员在派生类中的访问权限属性,若欲恢复其访问权限,则应作调整②方法:在派生类相应访问权限段中加以说明:基类名:: 成员名;③访问声明只能对变量或函数名,不能说明类型和参数④基类成员被调整后,在派生类中的访问权限既不能扩大也不能减小,即不能改变所属权限段⑤私有成员的访问权限不可调整,不能对私有段成员作访问声明⑥重载函数只需一个声明即可,具有不同访问权限的重载函数名不能作访问声明三、派生类的成员(1)由两部分组成:①派生类从基类继承来的成员,其封装体叫基类子对象(匿名对象)②派生类自定义成员(2)派生类对象的内存长度是基类数据成员和派生类自定义数据成员的内存空间之和(3)基类的私有成员在派生类中存在,但不可访问,不可见(4)静态成员受访问权限符的限制,但不受继承方式的制约派生类可用“基类名:: 静态成员名”访问基类的static成员(5)派生类共有四种成员:①公有成员②保护成员③私有成员④不可直接访问的成员,它由基类私有成员派生而来的(6)派生类直接访问基类私有成员的方法:①将基类私有段成员放于基类保护段②将派生类或派生类的成员函数声明为基类的友元四、改造基类成员(1)通过继承方式来控制基类成员在派生类中的访问权限(2)对基类成员进行同名覆盖①在派生类中声明一个与基类成员同名的新成员以屏蔽(隐藏)基类同名成员②在派生类中或通过派生类对象只能访问到派生类中新定义的同名成员③若在派生类中欲调用被编译器隐蔽起来的基类同名成员,则应作访问声明,明确指定基类类范围:对象名.基类名:: 成员名对象名.基类名:: 成员函数名(参数表)④同名覆盖时要求派生类与基类同名的新成员函数原型相同,数据成员的名字和类型相同当同名的基类成员函数和派生类成员函数的参数个数、类型和顺序不完全相同时,则属于函数重载⑤当欲对从基类继承过来的某些函数功能进行扩充和改造时,都可用同名覆盖原则来实现五、派生类的构造函数(1)派生类对象的数据结构,由基类数据成员和派生类自定义数据成员共同构成(2)构造函数不能被继承,基类子对象只能通过基类构函来初始化,常以成员初始化列表方式进行(3)定义:派生类名(总参数表):基类名(参数表),子对象名(参数表2),……{派生类自定义数据成员的初始化;}(4)派生类构造函数的调用执行顺序:①基类构造函数:先兄长②子对象类的构函:后客人③派生类构函:最后自己(5)当基类有无参数或缺省构函或未显式定义任何构函时,派生类构函中可省去对基类构函的调用(6)当基类构函有参数时,则派生类必须定义构函,以提供参数传递的途径(7)当派生类的基类也是一个派生类时,则每个派生类只需负责其直接基类构函的调用六、派生类的析构函数(1)析构函数不能被继承,基类子对象只能通过基类析构函数类释放(2)析构函数调用执行顺序与构函相反:①派生类析构函数:先自己②子对象类析构函数:再客人③基类析构函数:最后兄长七、赋值相容原理(1)即当派生类从基类公有继承时,派生类对象可自动隐式地转换一个基类对象(2)当公有继承时,在需要基类对象的任何地方,都可以使用公有派生类的对象来替代即公有派生类对象可以作为基类对象使用,但只能使用从基类继承来的成员(基类子对象)(3)公有派生类的对象、对象指针、对象引用都适用于基类对象、对象指针、对象引用所能使用的场合(4)赋值相容性不可逆若欲将基类对象指针转换成公有派生类对象指针,则必须显式进行类型转换不允许用基类对象给派生类对象赋值(5)也称为子类型对父类型的类型适应①子类型:对类型S,当且仅当它至少提供了类型T的行为,则称S是T的子类型②公有继承时,基类为父类型,派生类为子类型,派生类适应于基类③类型适应:若一个函数可用于父类型的对象,则它也可用于其各个子类型的对象(6)是多态性的基础,提高了编程效率八、多层继承(1)所有派生类都只需对其直接基类负责:派生类构函只需向其直接基类传递参数(2)可实现抽象机制和软件重用机制§4—3多继承一、多继承即多重继承①是单继承的扩展和组合,单继承可看作是多继承的特例②派生类有两个或两个以上的直接基类③派生类与每个基类之间仍可看作单继承④赋值相容性原理对多继承同样成立⑤同名覆盖规则对多继承仍成立⑥一个类不能多次被说明为同一个派生类的直接基类,即一个类不可以从同一个类中直接继承一次以上(可改用子对象方式)⑦可采用DAG图示法来表示各个基类与派生类的关系:箭头指向基类⑧一个类可以多次成为同一个派生类的间接基类二、多继承的构造函数与析构函数(1)定义:派生类名(总参数表):基类名1(参数表1),基类名2(参数表2),…,子对象名(参数表n),……{派生类构造函数体;}(2)派生类构函调用执行顺序:(与单继承相同)①先执行基类构函:先兄长②再执行子对象类构函:再客人③最后执行派生类本身的构函:最后自己(3)处于同一层次的各基类构函的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构函定义的成员初始化列表各项顺序无关(4)析构函数的调用执行顺序与构函相反三、多继承中的二义性问题(1)即派生类对基类成员访问的不唯一性(继承的模糊性)(2)调用不同基类的相同成员时可能出现二义性措施:使用作用域运算符,用类名对成员加以限定3)访问共同基类的成员时可能出现二义性措施:①用类名限定法来消除二义性,只能用派生类的直接类名来限定②在派生类中重定义一个与基类中同名的成员,以覆盖之③将公共基类说明为虚基类,使之在派生类中只有一个拷贝4)二义性检查是在访问控制和类型检查之前进行的,故只要不同基类有同名成员时,均会出现二义性,即使只有一个可被派生类访问或只有一个名字的类型符合要求(5)存在二义性,则编译时出错§4—4 虚基类1.即虚拟基类2.若类A是派生类C多条继承路径上的一个公共基类,则A在C的对象中将产生多个基类子对象若欲使其只有一个拷贝,则需将A设置为虚拟基类3.引入虚基类的目的:解决二义性问题,使派生类中只有公共基类的一个数据副本4.定义:class 派生类名:virtual 继承方式基类名5.虚基类子对象只被初始化一次,虚基类构函也只被执行一次6.若虚基类构函带有参数,则其直接或间接派生类的构函成员初始化列表中均应列出对虚基类构函的调用,但只有最后派生出来的用于声明对象的类对虚基类构函的调用才会被执行7.在同一层次中,虚基类构函先于非虚基类构函执行8.可节省内存空间,程序也更简洁9.一个类在作为某些类的虚基类的同时,还可以作为另一些派生类的非虚基类10.若虚基类由非虚基类派生而来,则先调用基类构函,再调用派生虚基类构函11.virtual常用于声明虚基类的直接派生类,可放于继承方式前,也可放于继承方式后面12.多继承时,virtual后紧跟的基类为虚基类,若有多个虚基类,则应用多个virtual来说明13.若同一层次中有多个虚基类,则其构函执行顺序取决于派生类定义时指定的顺序。
继承与派生
//C称为派生类
A对象成员
B对象成员
C对象成员 继承自A 继承自B C特有
东南大学软件学院(苏州 ) C++程序设计
一、继承与派生的概念
1.2 派生类的生成过程
吸收基类成员 ——除构造与析构函数外,全盘接收基
派c生lass employee{
类成员,派cla生ss类tec中hn不ica需n:p描ubl述ic employee{
class C: public B2, public B1, public B3 { public: //派生类的公有成员 C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b) {} private: //派生类的私有对象成员 B1 memberB1; B2 memberB2; B3 memberB3; }; int main() { C obj(1,2,3,4); }
东南大学软件学院(苏州 ) C++程序设计
二、派生类的构造函数和析构函数
2.2 多继承时派生类的构造函数与析构函数 1.首先会对派生类中新增的普通成员进行清理 2.然后会对派生类新增的对象成员进行清理 3.最后会对所有从基类继承而来的成员进行清理
东南大学软件学院(苏州 ) C++程序设计
三、多继承时的二义性问题
东南大学软件学院(苏州 ) C++程序设计
int main( ){ Student student(“zhangsan”,”123456”,’男’); Graduate graduate; student=graduate;
《继承和派生》课件
派生类的析构函数
派生类析构函数在销毁派生类对象时 自动调用,用于释放派生类所占用的 资源。
派生类析构函数可以包含代码,用于 清理派生类所占用的资源。
派生类析构函数可以访问基类的析构 函数,通过使用`this`关键字调用基类 析构函数。
派生类析构函数可以重载基类析构函 数,以便在销毁派生类对象时执行特 定的操作。
基类析构函数的调用
在派生类的析构函数中,可以通过使用`this`关键字调 用基类的析构函数,以确保基类资源得到正确释放。
输标02入题
如果在派生类的析构函数中没有显式调用基类的析构 函数,则编译器会自动调用基类的默认析构函数。
01
03
在某些情况下,可能需要显式调用基类的析构函数, 以确保资源得到正确释放。例如,当基类包含动态分
02 继承的方式
公有继承
总结词
公有继承是指子类可以访问父类的公有成员。
详细描述
在公有继承中,子类可以访问父类的公有成员(即不加任 何修饰符的成员),这些成员在子类中保持公有属性。子 类可以继承和使用父类的公有成员,包括函数、变量、常 量等。
总结词
公有继承是实现代码复用的一种方式。
详细描述
通过公有继承,子类可以继承父类的公有成员,从而避免 重复编写相同的代码。这有助于提高代码的复用性和维护 性。
注意事项
虚函数和纯虚函数的使用 应合理规划,避免过度使 用导致程序复杂度和维护 成本增加。
继承和派生的效率问题
继承
通过共享已存在的代码, 减少代码冗余。但也可能 导致内存浪费和性能下降 。
派生
通过扩展已有类,增加新 功能或修改已有功能。但 也可能导致内存消耗增加 和性能下降。
注意事项
继承与派生
子类是对父类的具体化 子类是父类的延续 子类是父类的组合
1.2 派生类的生成
• 吸收父类成员 将父类的成员数据与成员函数完整的,不加修改
1.3 继承方式
私有继承
在私有继承情况下,当父类的成员数据或成员函数的访 问权限是public或protected,当用户在子类中访问这些派 生而来的数据与函数时,其访问权限都是private,只有子 类自身的实例可以使用这些数据与函数。而在子类以外, 不能通过子类的成员函数来访问这些数据。而父类中的私 有成员在子类中是不能访问的。特别强调的是,即使是子 类派生而出的新的子类也不能访问这些数据与函数。也就 是说,在私有继承方式下,任何类只能派生出一个子类, 而当派生出子类在派生出新的子类时,最先的父类就不起 作用了。私有继承是C++中默认的继承模式。
的继承过来。
• 改造基类成员
对父类中的成员进行相关改造,使之更加符合派生子类的 要求。改造通过有两方面内容:访问权限与同名覆盖。
• 添加新成员
新的类与父类最突出的区别在于,用户在新的类中定义了 新的成员数据或成员函数。
1.3 继承方式
公共继承
在公共继承情况下,如果父类成员的访问权限是public 或protected时,子类继承而得的父类成员的权限不变。也 就是说,此时,父类的成员数据与成员函数被子类以公共 方式继承后,则用户在子类中访问这些派生而来的数据的 权限与在父类直接访问这些数据的权限一致。此时,用户 在子类外可以利用子类的对象访问这些数据。而当父类成 员的访问权限是private时候,子类不能访问这些私有成员。
继承和派生
派生类构造函数调用顺序:
基类的构造函数;
子对象的构造函数;
派生类构造函数体;
二、派生类的析构函数
析构函数不能被继承; 执行派生类的析构函数时,基类的析构函数也 将被调用;
析构函数的执行顺序与构造函数严格相反;
派生类的析构函数; 基类的析构函数;
[例]分析下列程序
#include <iostream.h> class B B::~B() {public: { cout<<"B's destructor called. "<<endl; } B(); void B::Print() const B(int i); { cout<<b<<endl; } ~B(); void Print() const; private: int b; }; B::B() { b=0; cout<<"B's default constructor called. "<<endl;} B::B(int i) { b=i; cout<<"B's constructor called. "<<endl; }
回答下列问题,并说明原因。
1、派生类B中成员函数f2()能否访问基类A的成员:f1()、j1和i1? 可以访问f1()和j1,不可以访问i1; 2、能否通过派生类B的对象b访问基类A成员:f1()、j1和i1? 可以访问f1(),不可以访问j1和i1; 3、派生类C的成员函数f3()能否访问直接基类B的成员f2()、j2 和i2?能否访问间接基类A的成员: f1()、j1和i1? 可以访问直接基类中的f2()和j2以及间接基类中的f1()和j1, 不可以访问i2和i1; 4、能否通过派生类C对象c访问直接基类B中的成员:f2()、j2和i2? 能否访问间接基类A中的成员: f1()、j1和i1?
继承与派生——精选推荐
继承与派⽣继承与派⽣概述:继承与派⽣是同⼀个过程从不同的⾓度看:保持已有类的特性⽽构成新类的过程称为继承在已有类的基础上新增⾃⼰的特性⽽产⽣新类的过程称为派⽣被继承的已有类成为基类(⽗类)base class派⽣出的新类称为派⽣类(⼦类)derived class直接参与派⽣出某类的基类成为直接基类基类的基类甚⾄更⾼层的基类称为间接基类继承的⽬的:实现设计与代码的重⽤,充分利⽤原有的类派⽣的⽬的:当新的问题出现,原有程序⽆法解决,需要对原有程序进⾏改造单继承时派⽣类的定义: class 派⽣类名:继承⽅式基类名{成员声明;}例⼦:class Derived: public Base{public:Derived();~Derived();};多继承时派⽣类的定义:class 派⽣类名:继承⽅式1 基类名1,继承⽅式2 基类名2,。
{成员声明;};例⼦:class Derived: public Base1, private Base 2{public:Derived();~Derived();};派⽣类的构成:吸收基类的成员,(默认情况下,派⽣类包含全部基类中除了构造函数之外的所有成员,C++11规定可以使⽤using语句继承基类构造函数)改造基类成员,(如果派⽣类中声明了⼀个和某基类成员同名的新成员,派⽣的新成员就隐藏或覆盖了外层同名成员)添加新的成员继承⽅式简介:三种继承⽅式:公有(public ),私有(private),保护继承(protected)重点写⼀下保护成员:在派⽣类中可以作为public,在基类中类似private。
(也就是说,如果想要把基类中的私有成员给派⽣类⽤,但是却⼜不想将此成员作为public成员,可以设定为protected成员,这样可以达到派⽣类可以访问的效果)私有继承:将除了私有成员的其他成员转换成派⽣类的私有成员派⽣类的构造函数:派⽣类新增成员:派⽣类定义构造函数初始化;继承来的成员:⾃动调⽤基类构造函数进⾏初始化;派⽣类的构造函数需要给基类的构造函数传递参数。
08第八章继承与派生
私有基类成员 私有成员 公有成员 保护成员来自在派生类中的访问 属性
不可访问 私有 私有
C++程序设计基础
8.4.3 保护成员和保护继承
由protected声明的成员称为“受保护的成员”,或简 称“保护成员”。
此外,在声明派生类时,一般还应当自己定义派生类的构 造函数和析构函数,因为构造函数和析构函数是不能从基类 继承的。
C++程序设计基础
实际上,并不是把基类的成员和派生类自己增加的成员简单 地加在一起就成为派生类。构造一个派生类包括以下3部分工 作:
(1)从基类接收成员。 派生类把基类全部的成员(不包括构造函数和析构函数)接收 过来,也就是说是没有选择的,不能选择接收其中一部分成员, 而舍弃另一部分成员。 要求我们根据派生类的需要慎重选择基类,使冗余量最小。 事实上,有些类是专门作为基类而设计的,在设计时充分考虑 到派生类的要求。 (2)调整从基类接收的成员。 接收基类成员是程序人员不能选择的,但是程序人员可以对 这些成员作某些调整。 (3)在声明派生类时增加的成员。 这部分内容是很重要的,它体现了派生类对基类功能的扩展。 要根据需要仔细考虑应当增加哪些成员,精心设计。
派生类中不可访问的成 员
在派生 类中 可以
可以
可以
不可以
在派生类 在下层公有派
外部
生类中
可以
可以
不可以
不可以
不可以
不可以
不可以
不可以
C++程序设计基础
8.5 派生类的构造函数
《继承和派生》PPT课件
完整版ppt
15
继承和派生
练习、设计一个圆类,从圆派生圆柱(或圆 锥),并设计成员函数输出圆柱(或圆锥) 的底面面积和体积。
完整版ppt
16
继承关系中构造函数之间的关系
• 派生类不继承基类的构造函数 • 派生类和基类的构造函数之间是一种自动调用的
关系 • 创建派生类对象时,派生类构造函数要调用基类
成员M基类中的存取权 成员M 在private继承后
限
的派生类的存取权限
public
private
protected
private
private
隐藏
完整版ppt
12
受保护继承(protected)和派生
• 基类中公有成员和受保护成员被继承后都是受 保护的
成员M基类中的存取权限 成员M 在protected继承后 的派生类的存取权限
性和行为 • 派生类可以修改继承的属性和行为 • 派生类可以增加新的属性和行为 • 派生类对象也是基类对象 • 派生类对象和基类对象可以被统一管理
完整版ppt
4
继承和派生的基本概念
基类
数据成员 函数成员
派生类
基类
数据成员 函数成员
自己的数据成员 自己的函数成员
完整版ppt
5
继承的意义
• 便于管理系统中的对象 • 系统扩充比较容易- 利用程序代码的再用性
继承和派生
继承和派生的基本概念 单一继承定义 派生类重定义基类函数 基类中成员被继承后存取权限等级的变化 继承关系中构造函数、析构函数之间的关
系 多重继承
完整版ppt
1
继承的例子
• 家具和柜子 • 建筑和房子 • 道路和高速公路 • 动物和猫 • 电视和彩色电视 • 电脑和笔记本电脑
继承与派生
C对象成员 继承自A 继承自B C特有
东南大学软件学院(苏州 ) C++程序设计
一、继承与派生的概念
1.2 派生类的生成过程 吸收基类成员
——除构造与析构函数外,全盘接收基
class employee{ 类成员,派生类中不需描述employee{ class technican:public 派生 private: private: 类成 char name[20]; float hourlyRate; 改造基类成员 ——1.基类成员的访问控制问题,2.基类 int individualNo; 员过 float workhours; int grade; 成员的同名覆盖问题 public: 程 public :
东南大学软件学院(苏州 ) C++程序设计
一、继承与派生的概念
class A { protected: int x; } class B: protected A{ public: void Function(); }; void B:Function() { x=5; //正确 }
class A { protected: int x; } int main() { A a; a.x=5; //错误 }
东南大学软件学院(苏州 ) C++程序设计
class B{ public: B(); B(int i); ~B(); void Print() const; private: int b; };
B::B() { b=0;
cout<<"B's default constructor called."<<endl; } B::B(int i) { b=i; cout<<"B's constructor called." <<endl; } B::~B() { cout<<"B's destructor called."<<endl; } void B::Print() const { cout<<b<<endl; }
第八章 继承与派生
一般来说,公有派生是绝对主流。
公有派生与私有派生
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++语言中,一个派生类可以从一个基类派生,也可以从 多个基类派生。从一个基类派生的继承称为单继承;从多个基类 派生的继承称为多继承。下图反映了类之间继承和派生关系。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
深圳大学实验报告
课程名称: C++程序设计
实验项目名称:继承与派生的基本概念
学院:信息工程学院
专业:通信工程
指导教师:张力
报告人:学号: 2011130151 班级: 2班实验时间: 2013年12月4日
实验报告提交时间: 2013年12月30日
教务处制
}
void Show(){
cout<<"x="<<x<<'\t'<<"y="<<y<<'\t'<<"radius="<<radius<<'\t'<<"height="< <height<<endl;
}
};
int main(){
Cylinder cy1(100,100,10,10),cy2(cy1),cy3;
cout<<"cy1 底面积:"<<cy1.Area()<<'\t'<<"cy1 侧面积:"<<teralArea()<<endl
<<"cy1 全面积:"<<cy1.GrossArea()<<'\t'<<"cy1 体积:"<<cy1.Volume()<<endl;
cy1.Show();
cout<<"cy2 底面积:"<<cy2.Area()<<'\t'<<"cy2 侧面积:"<<teralArea()<<endl
<<"cy2 全面积:"<<cy2.GrossArea()<<'\t'<<"cy2 体积:"<<cy2.Volume()<<endl;
cy2.Show();
cy3=cy1;
cout<<"cy3 底面积:"<<cy3.Area()<<'\t'<<"cy3 侧面积:"<<teralArea()<<endl
<<"cy3 全面积:"<<cy3.GrossArea()<<'\t'<<"cy3 体积:"<<cy3.Volume()<<endl;
cy3.Show();
return 0;
}
数据处理分析:
思考题:
(1)
(2)将x,y访问权限改成private,再运行,编译出错。
不允许private成员公开化。
(3)若不将Cline设为CPoint友元,需在Cline中重新定义点start和end。
实验结论:
通过这次的实验,又更深层次的体会了类的概念,通过类的继承与派生,我们可以由一个基类,派生出与之相对应又不完全相同的派生类,且派生类还能多层派生。
指导教师批阅意见:
成绩评定:
指导教师签字:
注:1、报告内的项目或内容设置,可根据实际情况加以调整和补充。
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。
如有侵权请联系告知删除,感谢你们的配合!。