• 【c++面试题】04-继承(详细版)



    1、从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

    2、继承的意义:

     便于管理系统中的对象
     系统扩充比较容易- 利用程序代码的再用性
     加快程序发展的速度
     减少程序的错误
    3、继承例子:家具和柜子 建筑和房子 动物和猫

    4、格式:

    (1)派生类的声明

    :class 派生类名:继承方式 基类名{派生类新增成员与方法的声明}

    (2)继承方式

    :类的三种访问权限—public protecd private
    继承的时候没有写继承方式,默认私有继承。

    (3)类成员的访问权限:

    在类中,我们是设计师,public, private, protected三种成员可以访问
    在对象中,我们是使用者,只有规定的接口public才可以访问;protected, private不能访问
    公有成员(public):可以被任何普通函数和任何类的成员函数访问(类和类外都可以访问)
    私有成员(private):可以被类自身的成员和友元访问,但不能被包括派生类在内的其他任何类和任何普通函数访问。(只能自己类内)
    保护成员(protected):可以被类自身的成员和友元访问外,还可以被派生类的成员函数访问,但不能被任何非友元的普通函数访问。(无继承关系,和private一样;有继承关系,派生类可访问基类protected)

    Ps:都可以在类内访问,只有public可以在类外访问。
    存在继承情况时:
    派生类可以直接访问父类的public、protected修饰的成员。
    成员变量一般使用私有访问控制。
    成员方法如果想要让子类访问,但是不想让外界访问,可以使用受保护的访问控制。

    5、好处:

    (1)提高代码的复用性
    避免重复代码,减少代码的冗余。
    (2)提高代码的维护性
    只需要修改一次父类的一些方法,不用每个子类修改。便于扩充。
    (3)类与类之间产生了关系,是多态的前提。

    6、弊端:

    (1)类的耦合性增加了
    开发原则:高内聚,低耦合
    耦合:类与类的关系
    内聚:自己完成一件事的能力

    7、继承关系中执行构造函数和析构函数的顺序:

    继承关系中的派生类创建对象:构造的执行顺序先走基类构造,再走派生类构造
    继承关系中的派生类释放对象:先走派生类析构,再走基类析构

    8、继承方式

    在这里插入图片描述
    在这里插入图片描述

    9、子类和父类出现同名非静态成员或函数

     子类和父类出现同名静态成员或函数,那么通过子类对象去访问该成员,访问的是子类中的成员。若子类没有父类中的成员,子类访问是父类的。
     如果存在同名成员,但子类想访问父类该成员,需要加上作用域。(Son.base::m_A)
     如果子类存在和父类同名的成员函数,子类会所有和父类同名的成员函数。(子类重定义父类的成员函数)
     如果想要调用父类中同名的成员函数,必须加上作用域。(son.Base::fun_c(10);)

    10、子类和父类出现同名静态(static)成员或函数

    (1)通过对象访问
    静态成员:static修饰,编译的时候就分配好了内存,类的所有对象都共享,类内(.h)声明,类外(.cpp)初始化。初始化格式:数据类型 类名::成员变量名=初始值;
    子类和父类出现同名静态成员,那么通过子类对象去访问该成员,访问的是子类中的成员。
    静态函数:子类和父类出现同名静态函数,那么通过子类对象去访问该函数,访问的是子类中的函数。要想访问父类同名函数,需使用域运算符。
    (2)通过类名访问
    类名::成员名或者函数名
    Son::m_A; Base::m_A; Son::Base::m_A;

    11、多重继承

    含义:一个类继承多个类
    语法格式:class 子类名 :继承方式 父类1,继承方式 父类2…(继承方式最好不要省略,默认为私有继承)
    特性
    (1) 若两个父类含有同名成员,子类访问需要加上作用域。

    12、菱形继承和虚继承

    菱形继承

    定义:两个派生类(B、C)继承同一个基类(A),又有一个类(D)同时继承着两个派生类。
    问题
    B、C同时继承A,当C访问A成员的时候,不知道访问的是B中的A还是C中的A,产生二义性。(解决:加作用域)
    C继承A的数据有两份,浪费内存。
    解决:使用虚继承,就不会产生二义性,C类可以直接访问赋值A成员。C.m_A=200;(若不是虚继承,这句就会报错,要加上B或C作用域)

    虚继承 virtual

    语法格式:B、C类继承A类时 class B:virtual public A{} 加virtual,A被称为虚基类。
    虚继承前,D类有两个A类的成员,分别通过B、C访问。
    虚继承后,D类就只有一个A类的成员
    Vbptr:虚基类指针
    原理:只有一个唯一的成员,通过保存虚基类指针,这个指针指向的是一张表(虚基类表)
    这个表中保存了当前获取到唯一的数据的偏移量。

    虚表
    每一个类都有一个虚表,虚表里放的是虚函数的地址,基类被很多派生类继承,派生类也有虚表,派生类中如果没有重写虚函数,那么派生类中虚表中保存的函数的地址是基类的虚函数的地址;如果自己有重写过虚函数,虚表中存放的是派生类中虚函数的地址。

  • 相关阅读:
    pom.xml中解决“vulnerable dependency maven:org.yaml:snakeyaml:1.33“警告问题
    使用TinyPNG API压缩图片
    攻防世界pwn题:Recho
    数学建模学习(101):车辆路线规划问题
    13.接口自动化学习-Pytest结合Yaml使用
    《012.SpringBoot+vue之在线考试系统》【前后端分离&有开发文档】
    内存一致性,指令重排序,内存屏障,volatile解析
    Azure的AI使用-(语言检测、图像分析、图像文本识别)
    发明专利一般多长时间受理
    【VRTK】【VR开发】【Unity】7-配置交互能力和向量追踪
  • 原文地址:https://blog.csdn.net/kin_16/article/details/126276575