(本文根据《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++学习之路—继承与派生(一):基本概念与基类成员的访问属性的更多相关文章

  1. C++ 派生类成员的访问属性

    派生类成员的访问属性: C++继承方式总共分为以下几种:public.private.protected三种(它们直接影响到派生类的成员.及其对象对基类成员访问的规则).(1)public(公有继承) ...

  2. C++学习之路—继承与派生(四)拓展与总结

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1    拓展部分 本节主要由两部分内容组成,分 ...

  3. C++学习之路—继承与派生(三):多重继承与虚基类

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...

  4. C++学习之路—继承与派生(二):派生类的构造函数与析构函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 由于基类的构造函数和析构函数是不能被继承的,所以 ...

  5. C++继承和派生练习(一)--关于vehicle基类

    Target:定义一个车(vehicle)基类 具有MaxSpeed.Weight等成员变量,Run.Stop等成员函数,由此派生出自行车(bicycle)类.汽车(motorcar)类. 自行车(b ...

  6. C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)

    4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...

  7. c++中派生类对基类成员的三种访问规则(转)

    C++中派生类对基类成员的访问形式主要有以下两种:1.内部访问:由派生类中新增成员对基类继承来的成员的访问.2.对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问.今天给大家介绍在3中 ...

  8. Qt 学习之路 2(73):Qt 线程相关类

    Home / Qt 学习之路 2 / Qt 学习之路 2(73):Qt 线程相关类 Qt 学习之路 2(73):Qt 线程相关类  豆子  2013年11月26日  Qt 学习之路 2  7条评论 希 ...

  9. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

随机推荐

  1. Python3.5.1 下使用HTMLParser报错

    pip 安装HTMLParser之后,import HTMLParser 使用的时候,报错"ImportError:Can't not find module markupbase" ...

  2. python IDE ulipad配置使用

    一直认为认为python自带的编辑器idle实在是太简陋了,连显示行号的功能都没有,也非常不好编辑.找了下windows平台下的Ide,发现ulipad很多人推荐使用,就开始安装了. 首先去官网: h ...

  3. Android Activity Fragment 生命周期

    从开源项目中看到 这个,就情不自禁的收藏了~ https://github.com/xxv/android-lifecycle

  4. PHP - 将HTML代码转义

    代码: 页面显示: 页面源码:

  5. 【CSDN博客之星评选】我为什么坚持写博客

    今天无意中在CSDN的博客之星评选活动看到自己竟然是候选人之一,真的是十分的惊讶也十分的高兴.对于喜欢写东西.喜欢分享的我来说,已经忍不住用文字来记录一下今天的美好心情,同时也让我回想起我是如何开始在 ...

  6. java--异常处理总结

    [在程序中抛出异常] 在程序中抛出异常,一定要使用关键字throw. throw+异常实例对象. public class Demo2 { public static void main(String ...

  7. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...

  8. Python 数据分析(二 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识

    Python 数据分析(二) 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识 第1节 groupby 技术 第2节 数据聚合 第3节 分组级运算和转换 第4 ...

  9. SQL之概念

    SQL即结构化查询语言,是一个功能强大的数据库语言,可以分为: 1.DML即数据操作语言,用于检索或者修改数据: 2.DDL即数据定义语言,用于定义数据的结构,如创建.修改.删除等: 3.DCL即数据 ...

  10. 基于Andoird 4.2.2的Account Manager源代码分析学习:AccountManagerService系统服务的添加

    从启动说起 Android系统加载时,首先启动init进程,该进程会启动Zygote进程.Zygote进程执行/system/bin/app_process程序.app_process程序在执行中,通 ...