C++学习之路—继承与派生(一):基本概念与基类成员的访问属性
(本文根据《c++程序设计》(谭浩强)总结而成,整理者:华科小涛@http://www.cnblogs.com/hust-ghtao,转载请注明)
1 基本思想与概念
在传统的程序设计中,人们无法利用现有的丰富的软件资源,造成软件开发中人力、物力和时间的巨大浪费,这是因为过去的程序设计方法和计算机语言缺乏软件重用机制。而作为面向对象的语言,C++强调软件的可重用性,通过继承机制,解决了软件的可重用性问题。在编程的领域,你经常会遇到具有类似属性,但细节或行为存在细微差异的组件。在这些情况下,一种解决方案是将每个组件声明为一个类,并在每个类中实现所有的属性,这将重复实现相同的属性。另外一种解决方案就是使用继承,从同一个基类( base class)中派生出类似的类,在基类中实现通用的功能,并在派生类中覆盖基本的功能,以实现其独特的行为。
大家注意几个概念:
“继承”就是在一个已存在的类的基础上建立一个新的类,已存在的类称为“基类( base class)”或者“父类( father class)”,新建立的类称为“派生类( derived class)”或“子类( son class)”。而什么是“派生”呢?,其实“继承”和“派生”是从不同角度说的同一件事,“继承”是从子类的角度看,子类从基类那里获得基类特性的现象就是继承;“派生”是从基类的角度看,是指基类产生一个子类的过程。另外,一个派生类只从一个基类派生,这称为单继承;一个派生类有两个或多个基类称为多重继承。
2 派生类的构成
派生类中的成员包括从基类继承过来的成员和新增加的成员两大部分。从基类继承过来的成员体现了派生类从基类而获得的共性,而新增加的成员体现了派生了的个性。构造一个派生类包括3部分工作。
(1)从基类接收成员。派生类把全部的成员(不包括构造函数和析构函数)接收过来。这样就会出现一种情况:有些基类的成员在派生类中是用不到的,但是也必须继承过来,会造成数据的冗余,这就要求我们要从已有的类中选择合适的类作为基类,使派生类的结构更加合理。
(2)调整从基类接收的成员。一方面,我们可以通过指定继承方式来改变基类成员在派生类中的访问属性。另一方面,可以在派生类中声明一个与基类成员同名的成员,则派生类中的新成员会覆盖基类的同名成员,注意:如果是成员函数,不仅应使函数名相同,而且函数的参数表也要相同,如果不相同,就成为函数的重载了。
(3)在声明派生类时增加的成员。我们要仔细考虑应当增加哪些成员,精心设计。
此外,在声明派生类时,一般还应当自己定义派生类的构造函数和析构函数,因为构造函数和析构函数是不能从基类继承的。
3 基类成员在派生类中的访问属性
我先给出结论,在作细致的分析:
表3.1 基类成员在派生类中的访问属性
| 在基类的访问属性 | 继承方式 | 派生类中的访问属性 |
| private | public | 不可访问 |
| private | private | 不可访问 |
| private | protected | 不可访问 |
| public | public | public |
| public | private | private |
| public | protected | protected |
| protected | public | protected |
| protected | private | private |
| protected | protected | protected |
类成员的访问属性一共分为4中:
①public:类内类外都可以访问。
②protected:类内可以访问,类外不可以访问,下一层的派生类可以访问。
③private:类内可以访问,类外不能访问。
④不可访问:类内类外都不能访问。
由以上表格可知:
(1)当继承方式为public时,称为公用继承,用公用继承方式建立的派生类为公用派生类,其基类称为公用基类。采用公用继承方式时,基类的公用成员和保护成员在派生类中仍然保持其访问属性,而基类的私有成员却成为派生类中的不可访问的成员。那大家肯定就有疑问了,既然是公用继承,为什么不让访问基类的私有成员呢?因为私有成员体现了数据的封装性,隐藏私有成员有利于测试、调试和修改系统。如果派生类的成员能访问基类的私有成员,那派生类和基类就没有了界限了,这就破坏了基类的封装性。切记,保护私有成员是一条很重要的原则。对于基类的私有成员,在派生类中可通过调用基类的公用成员函数来引用。
(2)当继承方式为private时,基类的公用成员和保护成员成为了派生类的私有成员,即派生类的成员函数能访问它们,而在派生类外不能访问。基类的私有成员成了派生类中不可访问的成员,只有基类的成员函数可以引用它们。对于不需要再往下继承的类的功能可以用私有继承方式把它隐藏起来,这样,下一层的派生类无法访问它的任何成员。
(3)保护成员和保护继承
由protected声明的成员称为“保护成员”。受保护的成员不能被类外访问,从类的用户的角度来看,protected成员等价于private成员。但有一点不同,protected成员可以被派生类的成员函数引用。如果基类声明了私有成员,那么任何派生类都是不能访问它们的,若希望在派生类中能访问它们,则应该把它们声明为保护成员。一般地,如果你看到一个类中声明了保护成员,就意味着该类可能要用作基类,在它的派生类中会访问这些成员。
当继承方式为protected时,基类的公有成员和保护成员在派生类中都成了保护成员,其私有成员仍为基类私有。
以上介绍了只有一级派生的情况,实际上常常有多级派生的情况。无论哪一种继承方式,在派生类中是不能访问基类的私有成员的,私有成员只能被本类的成员函数所访问。如果在多级派生时都采用公用继承方式,那么直到最后一级派生类都能访问基类的公用成员和保护成员。如果采用私有的继承方式,经过若干次派生之后,基类的所有成员已经都变得不可访问了。如果采用保护继承方式,在派生类外是无法访问派生类中的任何成员的。在经过多次继承之后,很难记清楚那些成员可以访问,那些成员不可以访问,极易出错。因此,在实际中,常用的是公用继承。
(在本文中“公有”和“公用”同义)。
C++学习之路—继承与派生(一):基本概念与基类成员的访问属性的更多相关文章
- C++ 派生类成员的访问属性
派生类成员的访问属性: C++继承方式总共分为以下几种:public.private.protected三种(它们直接影响到派生类的成员.及其对象对基类成员访问的规则).(1)public(公有继承) ...
- C++学习之路—继承与派生(四)拓展与总结
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1 拓展部分 本节主要由两部分内容组成,分 ...
- C++学习之路—继承与派生(三):多重继承与虚基类
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...
- C++学习之路—继承与派生(二):派生类的构造函数与析构函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 由于基类的构造函数和析构函数是不能被继承的,所以 ...
- C++继承和派生练习(一)--关于vehicle基类
Target:定义一个车(vehicle)基类 具有MaxSpeed.Weight等成员变量,Run.Stop等成员函数,由此派生出自行车(bicycle)类.汽车(motorcar)类. 自行车(b ...
- C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)
4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...
- c++中派生类对基类成员的三种访问规则(转)
C++中派生类对基类成员的访问形式主要有以下两种:1.内部访问:由派生类中新增成员对基类继承来的成员的访问.2.对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问.今天给大家介绍在3中 ...
- Qt 学习之路 2(73):Qt 线程相关类
Home / Qt 学习之路 2 / Qt 学习之路 2(73):Qt 线程相关类 Qt 学习之路 2(73):Qt 线程相关类 豆子 2013年11月26日 Qt 学习之路 2 7条评论 希 ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
随机推荐
- c,c++,java格式总结
c语言 java
- BZOJ 3544: [ONTAK2010]Creative Accounting( BST )
题意 : 一段序列 , 求一段子序列和取余 M 的最大值 其实是一道水题... 前缀和 , 然后就是找 ( sum( r ) - sum( l ) ) % M 的最大值 . 考虑一个 sum( r ) ...
- IPython在Windows 7上的搭建步骤
安装篇 pip install jupyter 使用篇 启动本地notebook,打开Windows命令行,键入:ipython notebook
- Python之路Day8
摘要: Socket编程 异常处理 线程.进程 1.socket编程 1.1 socket 三次握手,注意阻塞的应用. 1.2 socketserver(2.x写作:SocketServer) 实现多 ...
- VC中关于 0xcccccccc和 0xcdcdcdcd异常
VC在调试时,可能会报“写入位置0xcccccccc 时发生访问冲突”,或者“写入位置0xcdcdcdcd 时发生访问冲突”,这些问题可能是由于使用了未初始化的指针引起的. 在 Debug 模式下,V ...
- BZOJ 3685: 普通van Emde Boas树( 线段树 )
建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ---------------------------------------- ...
- sencha touch笔记(5)——DataView组件(1)
1.DataView组件可以显示列表,图像等等的组件或者元素,特别适用于数据仓库频繁更新的情况.比如像显示新闻或者微博等等的很多相同样式的组件的列表这种一次性从后台或者数据源拿取很多数据展示的样式.比 ...
- 关于php判断中文字符的问题
在网上找了好多例子,还是这个靠谱点: UTF-8匹配: 在javascript中,要判断字符串是中文是很简单的.比如: var str = "php编程"; if (/^[\u4e ...
- 我的CSS架构
写在前面 都是自己看别人的架构,自己积累下来的一些东西,这里只是阐述自己的一些观念.借此希望同行交流交流下看法,共勉. 不同架构的CSS 业务流程不同,团队配员不同.会有各种各样的CSS架构. 有的会 ...
- js判断IP js判断域名
<html> <head> <script language="javascript" type="text/javascript" ...