C++---继承和派生

继承和派生

  • 在C++中, 代码重用是通过继承机制来实现的
    • 继承, 就是在一个已经存在的类的基础上, 再建议一个新类
    • 从已经有的类派生出新的类, 派生类就继承了基类的特征, 包括成员和方法
  • 继承可以完成下面的功能
    • 在已有类的基础上添加新功能, 如数组类, 可以添加数学计算
    • 给类添加数据成员, 对于字符串类, 可以派生出一个类, 并添加指定成员表示颜色
    • 修改类方法的行为, 对于普通英雄类, 可以派生出拥有更丰富技能的近战英雄类

使用继承

  • 基类定义公共内容, 统一修改

  • 派生类对象存储了基类的数据成员, 即派生类继承了基类的实现

  • 派生类对象可以使用基类的非私有函数, 即派生类继承了基类的接口

  • 派生类需要自己的构造函数

  • 派生类可以根据需要添加额外的数据成员和函数

  • 基类指针可以在不进行显示类型转换的情况下指向派生类对象

    Warrior warrior("诸葛达摩", 100, 10);
    Hero & refHero = warrior;
    Hero * ptrHero = &warrior;
    
    refHero.Move();		//基类引用调用函数
    ptrHero->Move();	//基类指针调用函数
    
  • 可以将派生类对象赋值给基类对象, 程序将使用隐式重载赋值运算符

    //基类引用指向的也是派生类对象
    Hero hero = warrior;
    hero.Move();
    
  • 基类指针或引用只能调用基类函数, 并不能调用派生类函数

  • 不可以将基类对象和地址赋给派生类引用和对象, 即不能做逆操作

  • 初始化对象时, 先调用基类的构造函数, 再调用派生类的构造函数; 释放对象时, 先调用派生类的析构函数, 再调用基类的析构函数

单继承

没有继承关系的内存模型

  • 没有继承时, 成员变量和成员函数会分开存储, 对象的内存只包含成员变量, 存储在栈区或堆区; 成员函数与对象内存分离, 存储在代码区
  • 编译器会分别为每个对象的成员变量分配内存, 但是所有对象都共享同一段函数代码
  • 类可以看做是一种复杂的数据类型, 使用sizeof求类所占用的空间大小, 只计算成员变量的大小, 不包含成员函数

有继承关系的内存模型

  • 有继承关系时, 派生类的内存模型可以看成是基类成员变量和新增成员变量的总和
  • 所有成员函数仍然存储在另外一个区域, 即代码区, 由所有对象共享

派生类成员的访问控制

公有继承

  • 基类的公有成员和受保护成员, 在派生类中保持原来的访问属性, 其私有成员仍为基类所独有

私有继承

  • 基类的公有成员和受保护成员, 在派生类中成为了私有成员, 基类的私有成员仍为基类所独有

受保护继承

  • 基类公有成员和受保护成员, 在派生类中成为了受保护成员, 私有成员仍为基类独有

image-20200505174523340

  • 公有权限下, 自己和派生类以及外部都可以访问
  • 私有权限下, 只能自己访问, 派生类以及外部都无法访问
  • 受保护权限下, 自己, 友元, 派生类可以访问, 外部无法访问

继承与组合

  • 在一个类中有另外一个类的成员作为数据成员, 这种方式叫做类的组合形式

  • 通过继承建立的派生类和基类, 是一种is-a "是"的关系, 比如 狗是动物.

  • 类的组合关系, 它们之间不是"是"的关系, 而是"有"的关系, 比如 学生有书包.

  • 继承是纵向的, 而组合是横向的

  • 继承时C与C++的最重要区别之一

    • C++源于C, C++最重要的特性就是引入了面向对象
    • C++中通常也可以直接使用C语言的习惯进行编程
  • 类的继承和组合是面向对象编程的核心

原文地址:https://www.cnblogs.com/KX-Lau/p/12857613.html