(本文根据《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. js模态窗口

    最近在看js,正好公司用的框架中用到了模态窗口,以前没有接触过,现在把模态窗口的用法先记下来. 常用的浏览器chrome,Firefox,ie11,这三种分别支持document.open(),win ...

  2. HTML文档类型声明的坑...

    如果发现js莫名其妙的报错(比如demo不报错,自己写的就报错),或者样式显示不正常,一定记得检查HTML页面里面加没加如下文档声明: <!DOCTYPE HTML PUBLIC "- ...

  3. Python 迭代器、生成器、递归、正则表达式 (四)

    一.迭代器&生成器 1.迭代器仅仅是一容器对象,它实现了迭代器协议.它有两个基本方法: 1)next 方法 返回容器的下一个元素 2)_iter_方法 返回迭代器自身.迭代器可以使用内建的it ...

  4. Xcode6项目运行在真机上未铺满整个屏幕

    如图 解决见图: 再次运行:

  5. spring mvc 和ajax异步交互完整实例

    Spring MVC 异步交互demo: 1.jsp页面: <%@ page language="java" contentType="text/html; cha ...

  6. Mojo 返回一维和二维数组

    这种情况不断的网数组@arr2里放入数据,返回的内容为: 这种情况是一维数组: while( $selStmt->fetch() ){ print "\$a1 is $a1\n&quo ...

  7. 基于visual Studio2013解决C语言竞赛题之0507筛选素数

     题目

  8. php 遍历文件夹及文件,获取文件名和文件路径存入数据库中

    <?php header("Content-Type:text/html; charset=gbk"); require('../../include/connect.php ...

  9. iOS 本地化应用程序(NSLocalizedString)

    App本地化的需要不用讲大家也都明白,本文将介绍一种简单的方法来实现字符串的本地化. 在不考虑本地化的情况下,我们如果在代码中给一个Button定义title,一般会这样写: btn.titleLab ...

  10. Aizu 1335 Eequal sum sets

    Let us consider sets of positive integers less than or equal to n. Note that all elements of a set a ...