转载自https://www.cnblogs.com/33debug/p/6666939.html

1、继承与派生

   继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一。简单的说,继承是指一个对象直接使用另一对象的属性和方法。继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程。C++中的继承关系就好比现实生活中的父子关系,继承一笔财产比白手起家要容易得多,原始类称为基类,继承类称为派生类,它们是类似于父亲和儿子的关系,所以也分别叫父类和子类。而子类又可以当成父类,被另外的类继承。继承的方式有三种分别为公有继承(public),保护继承(protect),私有继承(private)。
定义格式如下:

2、继承方式及访问属性

(1) 公有继承(public)

公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。

(2)私有继承(private)

私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。

(3)保护继承(protected)

保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

  private能够对外部和子类保密,即除了成员所在的类本身可以访问之外,别的都不能直接访问。protected能够对外部保密,但允许子类直接访问这些成员。public、private和protected对成员数据或成员函数的保护程度可以用下表来描述:举个栗子:

 1 class Base    //父类
2 {
3 private:
4 int _priB;
5 protected:
6 int _proB;
7 public:
8 int _pubB;
9 } ;
10 class Derived: public Base //子类,继承自base,继承类型为公有继承
11 {
12 private:
13 int _d_pri;
14 protected:
15 int _d_pro;
16 public:
17 void funct()
18 {
19 int d;
20 d=_priB; //error:基类中私有成员在派生类中是不可见的
21 d=_proB; //ok: 基类的保护成员在派生类中为保护成员
22 d=_pubB; //ok: 基类的公共成员在派生类中为公共成员
23 }
24 int _d_pub;
25 } ;
总结:(1). public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用, 因为每个子类对象也都是一个父类对象。
26 class C :private Base //基类Base的派生类C(私有继承)
27 {
28 public:
29 void funct()
30 {
31 int c;
32 c=_priB; //error:基类中私有成员在派生类中是不可见的
33 c=_proB; //ok:基类的保护成员在派生类中为私有成员
34 c=_pubB; //ok:基类的公共成员在派生类中为私有成员
35 }
36 };
37 class E :protected Base //基类Base的派生类E(保护继承)
38 {
39 public:
40 void funct()
41 {
42 int e ;
43 e=_priB; //error:基类中私有成员在派生类中是不可见的
44 e=_proB; //ok:基类的保护成员在派生类中为保护成员
45 e=_pubB; //ok:基类的公共成员在派生类中为保护成员
46 }
47 };
总结:
(2). 基类的private成员 在派生类中是不能被访问的, 如果基类成员 不想在类外直接被访问, 但需要 在派生类中能访问, 就定义为protected。 可以看出保护成员 限定符是因继承才出现的。
(3). protected/private继承是一个实现继承, 基类的部分成员 并非完全成为子类接口 的一部分, 是 has-a 的关系原则, 所以非特殊情况下不会使用这两种继承关系, 在绝大多数的场景下使用的 都是公有继承。 私有继承以为这is-implemented-in-terms-of(是根据……实现的) 。 通常比组合(composition) 更低级, 但当一个派生类需要访问 基类保护成员 或需要重定义基类的虚函数时它就是合理的。
49 int main()
50 {
51 int a;
53 D d;
54 a=D._priB; //error:公有继承基类中私有成员在派生类中是不可见的,对对象不可见
55 a=D._proB; //error:公有继承基类的保护成员在派生类中为保护成员,对对象不可见
56 a=D._pubB; //ok:公有继承基类的公共成员在派生类中为公共成员,对对象可见
58 C c;
59 a=c._priB; //error:私有继承基类中私有成员在派生类中是不可见的, 对对象不可见
60 a=c._proB; //error:私有继承基类的保护成员在派生类中为私有成员,对对象不可见
61 a=c._pubB; //error:私有继承基类的公共成员在派生类中为私有成员,对对象不可见
63 E e;
64 a=e._priB; //error:保护继承基类中私有成员在派生类中是不可见的, 对对象不可见
65 a=e._proB; //error:保护继承基类的保护成员在派生类中为保护成员,对对象不可见
66 a=e._pubB; //error:保护继承基类的公共成员在派生类中为保护成员,对对象不可见
67
68 return 0;
69 }

(4). 不管是哪种继承方式, 在派生类内部都可以访问基类的公有成员和保护成员 , 基类的私有成员存在但是在子类中不可见( 不能访问) 。
(5). 使用关键字class时默认的继承方式是private, 使用struct时默认的继承方式是public, 不过最好显式的写出继承方式。
(6). 在实际运用中一般使用都是public继承, 极少场景下才会使用protetced/private继承。

在struct继承中,如果没有显式给出继承类型,则默认的为public继承;在class继承中,如果没有显式给出继承类型,则默认的为private继承;

继承关系&访问限定符

C++学习二继承的更多相关文章

  1. ReactJS入门学习二

    ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...

  2. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  3. DjangoRestFramework学习二之序列化组件、视图组件 serializer modelserializer

      DjangoRestFramework学习二之序列化组件.视图组件   本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组 ...

  4. SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  5. day 90 DjangoRestFramework学习二之序列化组件

      DjangoRestFramework学习二之序列化组件   本节目录 一 序列化组件 二 xxx 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组件 首先按照 ...

  6. C++学习_继承覆盖重载

    今天通过对实验二继承,重载,覆盖的学习,让我更深一步理解了这些概念的区别. 首先来明确一个概念,函数名即地址,也就是说函数名就是个指针. 编译阶段,编译器为每个函数的代码分配一个地址空间并编译函数代码 ...

  7. C++学习之继承篇

    今天通过对实验二继承,重载,覆盖的学习,让我更深一步理解了这些概念的区别. 首先来明确一个概念,函数名即地址,也就是说函数名就是个指针. 编译阶段,编译器为每个函数的代码分配一个地址空间并编译函数代码 ...

  8. day 88 DjangoRestFramework学习二之序列化组件、视图组件

    DjangoRestFramework学习二之序列化组件.视图组件   本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组件 ...

  9. Go基础学习(二)

    数组[array] 数组定义[定义后长度不可变] 12 symbol := [...]string{USD: "$", EUR: "€", GBP: " ...

随机推荐

  1. babel-polyfill

    babel-polyfill Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator.Generator.Set.Maps.Proxy.Reflec ...

  2. for循环循环时间

    )) { Console.WriteLine(dt); } ("2011-5-5")       按需求定义 AddDays函数,   一天一天的增长

  3. Java平台编写运行Ruby和Python

    Java不仅是一门编程语言,还是一个平台,通过JRuby和Jython,我们可以在Java平台上编写和运行Ruby和Python程序.

  4. 完全使用css编写复选框

    在日常的项目中,出现复选框或者单选框,应该都属于常见需求了,最开始阶段,一般只有两种可能性: 一.完全使用  <input type="checkbox" />或者&l ...

  5. ubuntu 16042 安装过程

    IDE接口的硬盘被称为hd SCSI和SATA接口的硬盘则被称为sd 第1块硬盘称为sda, 第2块硬盘称为sdb 一块硬盘最多有4个主分区,主分区以外的分区称为扩展分区,硬盘可以没有扩展分区,但是一 ...

  6. val和var和Java

    object Hello { def main(args :Array[String]) { val k = i } } jvm代码 public final class Hello$ { publi ...

  7. SUSE 图形化界面/How to enable/disable AS Java Safe Mode

    vncserver 不同的用户使用不同的图形化环境变量 比如sidadm用户要启动configtools.sh 需要sidadm来启动图形化 如何将java切换成safe mode 2125707 - ...

  8. elk之[logstash-input-file]插件使用详解

    https://www.cnblogs.com/xing901022/p/4805586.html http://www.cnblogs.com/xing901022/p/4802822.html   ...

  9. nodejs操作monggodb数据库封装

    var MongoClient=require('mongodb').MongoClient; var DbUrl='mongodb://localhost:27017/productmanage'; ...

  10. layui动态options

    layui 坑 layui 针对各种表单元素做了较为全面的UI支持,你无需去书写那些 UI 结构,你只需要写 HTML 原始的 input.select.textarea 这些基本的标签即可.我们在 ...