类的组合,类的继承

类的组合(汽车类,轮子类,此时可以把轮子类组合到汽车类;)

类的继承(交通工具类,汽车类,此时汽车类可以派生自交通工具类;)

组合:常用描述has a..

继承:常用描述is a ..

如果既可以用组合又可以用派生解决,那首选组合方式;

继承与派生的目的  
  继承的目的:实现设计和代码的重用

  派生的目的:当新的问题出现,原有程序无法解决,需要对原有的程序进行改造

派生类的构成

  吸收基类的成员

  改造基类的成员

  添加新的成员

吸收基类的成员

  默认情况下派生类包含了全部的基类中除了构造函数和析构函数之外的所有的成员

  C++11规定可以使用using语句继承基类的构造函数

改造基类成员

  如果派生类声明了一个和某基类成员同名的新成员,派生类的新成员就隐藏或者覆盖了外层同名的成员

公有继承:
派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问直接访问基类中的private成员;

通过派生类的对象:只能访问public的成员

私有继承(private):
继承的访问控制:
基类的public和protected成员:都以private身份出现在派生类中;
基类的private成员:不可以直接访问
访问权限:
派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的
private成员;
通过派生类的对象不能访问从基类中继承的任何成员;

保护继承(protected):
继承的访问控制:

基类的public和protected成员:都以protected身份出现在派生类中

基类的private成员:不可以直接访问

访问权限:
派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问基类中的private成员;

通过派生类的对象:不能直接访问从基类继承的任何成员;

protected成员的特点和作用

对建立其所在类对象的模块来说,它与private成员的性质相同

对于其派生类来说,它与public成员的性质相同

既实现了数据隐藏,又方便继承,实现代码的重用

class A {

protected:

  int x;
};

int main()

{

  A a;

  a.x = 5;//错误

}

类型转换

  • 公有派生类对象可以被当作基类的对象使用,反之则不行;
  • 派生类的对象可以隐含转换为基类的对象
  • 派生类的对象可以初始化基类的引用
  • 派生类的指针可以隐含转换为基类的指针
  • 通过基类对象名、指针只能使用从基类继承的成员

注意:不要重新定义继承而来的非虚函数

默认情况下:

基类的构造不被继承,派生类需要定义自己的构造函数;

C++11规定

可以使用using语句继承基类构造函数;

但是只能初始化从基类继承的成员;对于派生类新增的成员无法完成初始化;

语法形式:

using B::B;

若不继承基类的构造函数

派生类新增的成员:派生类定义构造函数完成初始化

继承来的成员:自动调用基类的构造函数初始化

派生类的构造函数需要给基类的构造函数传递参数;

单继承时构造函数的定义语法:

派生类名::派生类名(基类所需的形参,本类成员所需的形参):

基类名(参数表),本类成员初始化列表

{

//其他的初始化操作

}

派生类与基类的构造函数

当基类有默认的构造函数时

派生类构造函数可以不向基类的构造函数传递参数;

构造派生类的对象时,基类的默认构造函数将被调用;

如需要执行基类中带参数的构造函数,那么

派生类构造函数应该为基类构造函数提供参考;

多继承且有对象成员时派生的构造函数定义语法

派生类名::派生类名(形参表):

基类名1(参数),基类名2(参数),...基类名n(参数),

本类成员(含对象成员)初始化列表

{

//其他的初始化操作

}

注释:此处的本类成员指的是类的成员,当然也可以是本类包括的其他类的对象;

执行次序按照定义时候的顺序执行;

派生类的复制构造函数:
若派生类没有声明复制构造函数,则编译器会在需要时生成一个隐含的复制构造函数;

先调用基类的复制构造函数;

再为派生类新增的成员执行复制;

若派生类定义复制构造函数

一般都要为基类的复制构造函数传递参数,复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数;

基类的复制构造函数形式参数类型是基类对象的引用,实参可以是派生类对象的引用;

例如:

C::C(const C &c1):B(c1) {}

访问从基类中继承的成员时,

当派生类与基类中有相同的成员时:

1.若没有特别的限定,则通过派生类对象使用的是派生类中的同名成员;

2.如要通过派生类对象访问基类中被隐藏的同名成员,可以使用基类名和作用域操作符号::来限定;

二义性问题:
如果从不同的基类继承了同名的函数,但是在派生类中没有定义同名的成员,派生类对象名或引用名 .成员名,“派生类指针->成员名”访问存在二义性问题。

解决方式:用类名限定

当继承多个基类时(假如两个基类又继承自另一个相同的类,此时容易出现继承相同数据的情况),容易导致继承内容相同的情况,在操作过程中容易导致数据的冗余以及数据的不一致;

虚基类

问题:

  当派生类从多个基类派生,而这些基类有共同的基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性;

方案:

  声明虚基类

  以virtual说明基类继承方式

  例:class B1:virtual public B

作用:

  主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题;

  为最远的派生类提供唯一的基类成员,而不是重复产生多次复制;

注意:

  在第一级继承时就要将共同基类设计为虚基类;

虚基类以及其派生类的构造函数

建立对象时所指定的类称为最远派生类;

虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。

在整个继承结构中,直接或者间接继承虚基类的所有派生类,都必须在构造函数的成员初始化列表中为虚基类的构造函数列出参数。如果未列出,则表示调用该虚基类的默认构造函数;

在建立对象时,只有最远派生类的构造函数调用基类的构造函数,其他类对虚基类构造函数的调用被忽略。

目标:降低程序的复杂性,提高代码的可复用性。

http://www.xuetangx.com/courses/course-v1:TsinghuaX+00740043_2x_2015_T2+sp/courseware/8d1fd477f469492ba2c1297e6ace6f5d/2a889505dd584a639363f2b4e8726040/

C++学习笔记44:继承与派生的更多相关文章

  1. 【C++学习笔记】继承与派生基础概念

    面向对象的程序设计主要有四个特点:抽象.封装.继承和多态.其中继承是我认为最最重要的一个特性,可以说继承是面向对象的精华所在. 举一个继承的浅显易懂的例子:假如我们已经有了一个“马”的类,其中成员变量 ...

  2. c++学习笔记之继承篇

    title: c++学习笔记之继承篇 date: 2017-03-26 16:36:33 tags: [c++,继承,public,virtual,private,protected] categor ...

  3. [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. CUBRID学习笔记 44 UPDATE 触发器 更新多表 教程

    cubrid的中sql查询语法UPDATE c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com ...

  5. C++学习之路—继承与派生(一):基本概念与基类成员的访问属性

    (本文根据<c++程序设计>(谭浩强)总结而成,整理者:华科小涛@http://www.cnblogs.com/hust-ghtao,转载请注明) 1   基本思想与概念 在传统的程序设计 ...

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

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

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

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

  8. C++学习笔记 封装 继承 多态 重写 重载 重定义

    C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...

  9. Java学习笔记之继承

    一.继承的基础 在Java术语中,被继承的类叫超类(superclass)或者父类,继承超类的类叫子类(subclass). 举例说明: class Box { public double width ...

随机推荐

  1. openssl版本升级操作记录【转】

    需要部署nginx的https环境,之前是yum安装的openssl,版本比较低,如下:   [root@nginx ~]# yum install -y pcre pcre-devel openss ...

  2. windows上python上传下载文件到linux服务器指定路径【转】

    从windows上传文件到linux,目录下的文件夹自动创建 #!/usr/bin/env python # coding: utf-8 import paramiko import datetime ...

  3. expdp和impdp导入和导出数据

    一  关于expdp和impdp     使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程 ...

  4. plsql developer导入导出序列方法

    导出: 1.打开PLSQL Developer,工具 2.类型排序,选中所有sequence,指定用户,单个文件,选择导出文件路径,等待执行完毕即可. 导入: 打开导出的文件,复制,在新打开的命令窗口 ...

  5. Android 图片平铺效果

    我们大家都看过平铺的效果,那么我们都是怎么样才能实现的那,我们其实主要用到的就是api,我们一开始new一个bitmap,就可以了,但是,大家都没有想过,我们还可以用什么方法来做这个事情那,那么我们就 ...

  6. Ex 5_28 Alice想要举办一个舞会..._第十次作业

    根据总人数建立顶点数量为总人数的无向图,顶点之间有边相连表示两个人相互认识,没有边则表示不认识.对于每一个顶点v,设d(v)表示顶点的度,若d(v)<5,即v认识的人数少于5,则不邀请v,若d( ...

  7. Dotfuscator使用

    参考:https://www.cnblogs.com/xiezunxu/articles/7228741.html

  8. Oracle 网络配置与管理

    [学习目标] Oracle 监听器是一个服务器端程序,用于监听所有来自客户端的请求,并为其提供数 据库服务.因此对监听器的管理与维护相当重要.         本章主要内容是描述对Oracle 监听器 ...

  9. IntelliJ IDEA2017 使用教程

    一:安装教程 请参考<Windows7下安装与破解IntelliJ IDEA2017> 二:目录说明 三:开发界面

  10. python之鸭子类型

    python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 在程序设计中,鸭子类型是动态类型的一种风格,不是由继承特定的类或实现特定的接口,而是当前的方法和属性的集合决定,鸭子 ...