本章将会从下面的5个部分进行讲解。
目录
1.继承的基本概念
1.1 是什么
继承就是在父类的基础上派生出子类,让子类变得富有。子类具有父类的属性与行为。
1.2 怎么用
这是它的简单使用。在继承方式上有三种方式,后面我将会详细的进行讲解。
1.3 访问限定符的使用


public 与 private 非常常见也是比较简单,但是 protected 比较少见它的作用主要体现在:派生类可以访问它修饰的成员,但是在类外面与 private 类型进行了封装不可以直接进行使用。
其次对于在继承的时候可能会有范围的变化我们只需要记住下面的话就可以:1.private 修饰的在派生的子类都是 private 都不可以访问。2. 如果是其他的派生类的它的访问限定符会变成最小的那一个。
2. 继承的作用域
2.1 切片
在这里提到了一个词语叫做:切片。是将子类的 对象 赋值给父类的对象/指针/引用。相当于对于进行了截断。
看到这里同学可能回问,那父类的可以不可以给子类。准确来说不可以,但是如果是对于基类指针再通过类型的强制转化赋值给子类的话可以实现,父类指针会造成越界访问,子类指针可以,但是会非法向下转型,可以使用dynamic_cast,后续会详细介绍。
2.2 作用域的变化
当我们进行继承,写出的子类的时候,可能会在方法与属性中存在相同的名字,那么如果是变量/属性的话叫做:隐藏(会隐藏父类的变量),方法的话是:重写(不是重载,因为不是在同一个作用域里面)。注意在实际中在继承体系里面最好不要定义同名的成员。
2.3 子类的默认构造函数
继承父类的成员变量,也会继承父类的默认构造函数。值得注意的是 子类 的构造函数,必须调用父类的构造函数,来对变量进行初始化,如果构造函数变成 private 则这个父类没办法被继承。其次拷贝构造与operator = 也是同样的必须调用父类的。最后析构函数可以不用显示定义。
整体的调用方法为:父类构造函数、子类构造函数、函数实现、子类析构函数、父类析构函数。
3. 静态成员
静态成员就是整个变量,被子类 与 父类同时共有。不同的访问限定符,得到的结果是一样的:public::count, private::count。
4. 菱形继承
4.1 是什么
菱形继承是指,一个子类同时继承了两个父类。在这种继承中,Assistant 会具有Person成员的两份。那么就会总成数据的冗余与二义性。为了解决整个问题,我们通过虚继承的方式进行解决。
4.2 解决方式
使用虚继承:class Student : virtual public Person.
class Teacher: vritual public Person.
这个继承的使用原来为:通过在定义 Student 与 Teacher 的时候我们都会开辟一个指针的空间,称为虚基表指针,通过这个指针找到虚基表,通过虚基表里面的偏移量找到对应的值。解决了上面的两个问题。
5. 总结与反思
5.1 继承与组合
继承也叫做白盒操作,具有(is a)的关系。也就是它的子类会看到父类函数方法的实现方式。比如动物、狗、猫。都是 is a。也就是前面的例子都是这种继承方式。
还有另外一种方式为:(has a)组合的方式,也叫做黑盒操作。这种方式,当子类去使用父类的时候由于是定义的 Person 变量。看不到具体是怎么实现的,通常:汽车有:轮胎、发动机。这样的就是组合。
5.2 其他
1. 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。
2. 多继承可以认为是C++的缺陷之一,很多后来的语言都没有多继承,如Java。
3. 后面还有几道面试题,我将会放到下章进行讲解。
(1). 什么是菱形继承?菱形继承的问题是什么?
(2). 什么是菱形虚拟继承?如何解决数据冗余和二义性的
(3) 继承和组合的区别?什么时候用继承?什么时候用组合?
以上是对于c++继承中简单的介绍。这个文章用于我的学习记录,如果是有其他的错误还请批评指正。如果对你有帮助还请给我点个赞👍👍👍。