类的组合,类的继承

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

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

组合:常用描述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. 常用的4个eclipse插件安装过程及使用方法

    最近整合了4个常用eclipse插件安装过程,分别是PMD.checkstyle.findbugs.sourcemonitor插件.因为我这里没有外网,所以所有的插件不是最新版,建议有网的童鞋自行在外 ...

  2. centos重启报错Umounting file systems:umount:/opt:device is busy

    系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...

  3. [转]Apache Commons IO入门教程

    Apache Commons IO是Apache基金会创建并维护的Java函数库.它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的 ...

  4. Go语言规格说明书 之 通道类型(Channel types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  5. abstract class 和 interface 区别

    本文出自与:heipai:tsg666 含有 abstract 修饰符的 class 即为抽象类,abstract 类不能创建的实例对象.含有 abstract 方法的类必须定义为 abstract ...

  6. html5手机 input file 上传图片 调用API

    <input type="file" accept="video/*;capture=camcorder"> <input type=&quo ...

  7. WAP网页中点击链接直接拨打电话的方法

    主要方法有两种: 第一种: 这种也是最简单的. 示例代码: <a href="tel:+18790853577">点击拨打</a> 第二种: <a h ...

  8. mysql批量插入数据优化

    一.问题 很早以前做了一个更新功能,就是将A表中的数据全部查找出来,相对B表中改变的数据更新B表,B表中没有的数据插入B表. 最近发现该功能执行速率减慢,有时还跑超时.原来是A表中数据渐渐变多,就有了 ...

  9. hdu 1711( 模式串T在主串S中首次出现的位置)

    Sample Input213 51 2 1 2 3 1 2 3 1 3 2 1 21 2 3 1 313 51 2 1 2 3 1 2 3 1 3 2 1 21 2 3 2 1 Sample Out ...

  10. python asyncio学习截图

    感觉对python越来越通了. 感觉不错, 截图