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++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
随机推荐
- int *p = NULL 和 *p = NULL(转载)
int *p = NULL 和 *p = NULL int *p = NULL; 这时候我们用编译器查看p的值为0x00000000.这句话的意思是定义一个指针变量p,其指向内存里面保存的是 ...
- 基于FPGA的DW8051移植(一)
最近 半个月都在移植8051,看到DW8051内核资料比较齐全又是新思发布的,所以就开始玩弄 可是这半个月的努力几近白费 —— 移植失败了,不知道从何着手这个内核.可能大家能找到不同的版本,我的是最初 ...
- 人人都用 Retina 屏幕的 MacBook Pro 笔记本电脑
自从今年年初 Apple 官网产品降价我立即买了 13 寸的 Retina 屏 MacBook Pro(rMBP)之后, 这款苹果的笔记本电脑就成了我在公司和家里的唯一电脑(就是这一款). 使用苹果的 ...
- Mojo 自动发布接口
get '/api/auto_publish/publish' => sub{ my $c = shift; my $env = $c->param('env'); my $app = $ ...
- java实现从实体到SQL语句的转换(二)
前面写过一篇生成insert语句的博客,今天把CRUD的都完善了一下,需要的上次写的获取实体信息的类,这里就不贴出来了[点击打开查看] 下面是完整的代码: package tan.code.utils ...
- poj3308 Paratroopers --- 最小点权覆盖->最小割
题目是一个非常明显的二分图带权匹配模型, 加入源点到nx建边,ny到汇点建边,(nx.ny)=inf建边.求最小割既得最小点权覆盖. 在本题中因为求的是乘积,所以先所有取log转换为加法,最后再乘方回 ...
- Python之路Day3
摘要: 复习day2内容 介绍set()-->归档到day2了... collections模块常用类 深浅copy的区别 自定义函数 文件操作 常用内建函数介绍 一.深浅copy的区别 #! ...
- cocos2d-x游戏开发系列教程-中国象棋01-工程文件概述
上一篇博文我们看到了象棋的效果图,这一张我们来看象棋代码的整体概述 让我们先对整个代码框架有个了解. 主目录: 主目录包含内容如上图: classes目录:业务代码 proj.win32:包括main ...
- js导出table到excel,同时兼容FF和IE
前台调用(第一个参数是table的id): <input value="导出" type="button" /> function toExcel( ...
- The type MultipartEntity is deprecated
在HttpCient4.3之前上传文件主要使用MultipartEntity这个类,但如今这个类已经不在推荐使用了(过时了).随之替代它的类是MultipartEntityBuilder.关于Mult ...