您的位置:首页 > 编程语言 > C语言/C++

C_PlusPlus学习笔记 - 6_继承与派生(C++语言程序设计【第三版】 郑莉等,清华大学出版社)

2014-06-30 17:59 639 查看
6——继承与派生

编写程序,在很大程度上是为了描述和解决现实世界中的现实问题。
C++中的类很好的采取了人类思维中的抽象和分类的方法,类与对象的关系恰当的反映了个体与同类群体共同特征之间的关系。
不同事物之间往往不是独立的,很多事物之间都有着复杂的联系。继承便是众多联系中的一种。
面向对象的程序设计中提供了类的继承机制,允许程序员在保持原有类特性的基础上,进行更具体、更详细的类的定义。以原有的类为基础产生新的类,我们就说新类继承了原有类的特征,也可以说是从原有类派生出新类。
类的派生机制有什么好处?
好处在于代码的重用性和可扩充性。
通过继承可以充分利用别人做过的一些类似的研究和已经有的一些分析、解决方案。
派生新类的过程一般包括吸收已有类的成员、调整已有类的成员和添加新的成员三个步骤。
类的继承和派生
所谓继承就是从先辈(父类)得到属性和行为特征。
类的继承是新的类从已有类那里得到已有的特性。从另一个角度看,从已有类产生新的类叫做派生。类的派生实际上是发展和演化的过程。

派生类的定义
class Dr1:public Base1,private Base2
{
public:
Dr1();

~Dr1();

}
一个派生类可以同时有多个基类,这种情况叫做多继承,这时派生类得到多个已有类的特征。
一个派生类只有一个直接基类的情况属于单继承。
单继承可以看做是多继承的一个最简单的特性,多继承可以看做是多个单继承的组合。
在派生过程中,派生出来的新类也同样可以作为基类再进行派生。
一个父类可以别多个派生类继承。这样就会形成一个相关联的类的家族,有时候也称作为类族。
在类族中直接参与派生出某类的基类叫做直接基类。而基类的基类成为间接基类。

继承方式
继承方式规定了如何访问从基类继承的成员。
公有继承,保护继承,私有继承三种方式。
如果不规定,则是私有继承。

派生类成员
派生类成员是指从基类继承来的所有成员之外的新增加的数据和函数成员。

派生类的生成过程
在C++程序设计中,进行了派生类的声明之后,给出该类的成员函数的实现,整个类就算完成了。可以由它来生成对象进行实际问题的处理。
派生新类的三个步骤:吸收基类成员、改造基类成员、添加基类成员。

访问控制
类的继承方式:
public, protected, private
公有继承
当一个类的继承方式为公有继承时,基类的公有和保护成员的访问属性在派生类中不变而基类的私有成员不可直接访问。
在派生类中,实际所拥有的成员就是从基类继承过来的成员与派生类新定义的成员的总和。继承方式为公有继承,这时基类的公有成员在派生类中访问属性保持原样,派生类的成员函数以及对象可以访问到基类的公有成员,但是无法访问基类的私有成员。基类原有的外部接口变成了派生类外部接口的一部分。
派生类的继承,也就实现了代码的重用。同时通过新增成员,加入了自身的独有特性,达到了程序的扩充。

私有继承
当类的继承方式为私有继承时,基类中的公有成员和保护成员都以私有成员的身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。私有继承之后,基类的成员再无法再以后的派生类中直接发挥作用,实际是相当于终止了基类功能的继续派生,一般情况下,私有继承用的较少。

保护继承
保护继承中,基类的公有和保护成员都以保护成员的身份出现在派生类中。而基类的私有成员不可直接访问。
保护成员的访问,可以通过类的继承来访问。

类型兼容规则
类型兼容规则是指在需要基类的任何地方,都可以使用公有派生类的对象来替代。
通过公有继承,派生类得到的基类中除了构造函数、析构函数之外的所有成员。这样,公有派生类就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
1.派生类的对象可以赋值给基类的对象
2.派生类的对象可以初始化基类的引用
3.派生类对象的地址可以赋给指向基类的指针。
在替代之后,派生类对象可以作为基类的对象使用,但只能使用基类继承的成员。

派生类的构造和析构函数
继承的目的是为了发展,派生类继承了基类的成员,实现了原有代码的重用,这只是一部分,而代码的扩充才是最重要的,只有通过添加新的成员,加入新的功能,类的派生才有实际意义。
基类的构造函数与析构函数不能被继承,如果要对新增成员进行初始化,必须要添加新的派生类的构造函数。
如果基类声明了一个带有形参表的构造函数时,派生类就应该声明构造函数,提供一个将参数传递给基类构造函数的途径,保证在初始化的时候能获得必要的数据。当然如果基类没有声明构造函数,派生类也可以不声明构造函数,全部采用默认构造函数。
构造函数的执行顺序和派生类构造函数中列出的名称顺序毫无关系。
基类构造函数的调用顺序是按照派生类声明时的顺序。

派生类的拷贝构造函数
如果没有编写会调用拷贝构造函数。
C::C(C &c1):B(c1)

派生类的析构函数
派生类的析构函数的功能是在该类对象消亡时之前进行一些必要的清理工作。
析构函数没有类型也没有参数。
在派生过程中,基类的析构函数也不能继承下来,如果需要析构的话,必须在派生类中声明新的析构函数。派生类的析构方法只需把派生类新增的非对象成员的清理工作做好就行,系统会自动调用基类以及对象成员的析构函数来对基类及对象成员进行清理。其执行顺序和构造函数正好相反。

派生类成员的标识与访问
经过类的派生,就形成了一个具有层次结构的类族。
在派生类中,成员可以按照访问属性划分:
1. 不可访问成员 (基类私有成员继承而来的,派生类或是建立派生类对象的模块都没有办法访问)
2. 私有成员 (从基类继承过来的成员以及新增的成员,在派生类内部都可以访问,但是建立派生类对象的模块中无法访问,继续派生,就变成了新的派生类不可访问成员。)
3. 保护成员
4. 公有成员

在对派生类的访问中,实际上有两个问题
1. 第一是唯一标识问题,
2. 成员本身的属性问题。(可见性问题)
我们只能访问一个能够唯一标识的可见成员。如果通过一个表达式能引用的成员不只一个,称为有二义性。。。。

作用域分辨
::(作用域分辨符)
1. 可见性原则
如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层依然可见,如果在内层声明了同名标识符,则外层在内层不可见。内层就隐蔽了外层同名变量,这种现象叫隐蔽规则。要访问必须是作用域分辨符和基类名字来限定。
通过作用分辨符,就明确唯一标识了派生类中由基类所继承来的成员,达到了访问的目的,解决了成员被隐蔽问题。

如果派生类的部分或全部直接基类是从一个共同的基类派生而来,在这些直接基类中,从上一级基类继承来的成员就拥有相同的名称,因此派生类中就会产生同名现象,对这种类型的同名成员也要使用作用域分辨符来唯一标识,而且用直接基类进行限制。

虚基类:
当某类的部分或者全部直接基类是从另一个共同基类派生而来时,在这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称。在派生类的对象中,这些同名数据成员在内存中同时拥有多个拷贝,同一个函数名会有多个映射。可以将共同的基类设置为虚基类,这时从不同的路径继承过来的同名数据成员在内存中只有一个拷贝,同一个函数名也只有一个映射。

最远派生类
由最远派生类来初始化虚基类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐