• 【C++】继承与多态相关11道面试题整理


    目录

    01.什么是多态?

    02.什么是重载、重写、重定义?

    03.多态的实现原理?

    04.内联函数可以是虚函数吗?

    05.静态成员可以是虚函数吗?

    06.构造函数可以是虚函数吗?

    07.析构函数可以是虚函数吗?

    08.对象访问普通函数快还是虚函数快?

    09.虚函数表是在什么阶段生成的,存在哪的?

    10.什么是菱形继承、虚继承?

    11.什么是抽象类?抽象类的作用?


    01.什么是多态?

    分析:

    多态有两种类型:

    1.静态多态(编译时):通过函数重载和模版实现。

    2.动态多态(运行时):通过继承和虚函数实现。

    回答:

    静态多态:静态多态性是在编译时决定的,主要通过函数重载和模版实现。

    动态多态:动态多态性是在运行时决定的,通过在基类声明虚函数,在派生类中重写该函数,并通过基类指针或引用调用该函数,使得不同的类通过同一接口进行访问,从而实现不同的行为。

    02.什么是重载、重写、重定义?

    回答:

    重载:函数重载是指在同一作用域内,函数名相同但参数列表不同的多个函数(注:不能通过返回值重载函数),支持编译时多态。

    重写:重写也叫作覆盖,是指在派生类中重新定义基类中的虚函数的行为,其函数名、参数列表和返回值类型都要相同,支持运行时多态。(在派生类的虚函数表中,对应的基类虚函数被派生类虚函数覆盖)

    重定义:重定义又叫作隐藏,是指在派生类中定义一个与基类中同名的非虚函数或变量,使得基类的成员在派生类中被隐藏起来。(与重写的区别就在于定义的是否是虚函数)

    03.多态的实现原理?

    回答:

    多态的实现原理是通过在基类中声明虚函数,并在派生类中重写这些虚函数,程序在运行时通过虚函数表动态绑定实际调用的函数,从而实现同一接口在不同对象上的不同表现。

    04.内联函数可以是虚函数吗?

    分析:

    内联函数是一种编译器优化,编译器将函数体直接插入每次调用的地方,以减少函数调用的开销。内联函数的调用是静态绑定,是在编译时完成的。

    虚函数通过虚函数表实现动态绑定,允许派生类重写(覆盖)基类的函数,虚函数的调用是动态绑定,是在运行时实现的。

    可以看的出来,内联函数和虚函数在语义上有冲突,但是C++语法允许将虚函数声明为内联函数,此时内联函数的效果是在编译时展开函数体,但调用依然是通过虚函数表来进行动态绑定。

    回答:

    C++语法允许这么做,但此时函数调用是通过动态绑定完成的,这就忽略了inline自身的属性,此时这个函数就不是完全意义上的内联函数了。

    05.静态成员可以是虚函数吗?

    分析:

    静态成员函数是属于类而不是类的实例的成员函数,它不依赖于类的任何实例化对象存在。静态成员函数子啊整个类的声明周期中保持唯一的一份拷贝

    回答:

    虚函数的动态绑定需要在运行时根据对象的类型确定调用的函数版本,但静态成员函数在编译时已经确定了调用的版本,因此不适合作为虚函数。

    另一种回答:

    静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表中,因此不能定义为虚函数。

    06.构造函数可以是虚函数吗?

    分析:

    这个问题就像一个先有鸡还是先有蛋的问题。虚函数的调用依赖于对象的类型,构造函数在对象被创建时被调用,此时对象未构造完成,无法进行虚函数调用。

    回答:

    不能,对象中的虚函数表指针是在构造函数初始化列表阶段初始化的。

    07.析构函数可以是虚函数吗?

    分析:

    在继承当中,通过基类指针删除派生类对象时,我们需要找到对应的析构函数,这样才能正确释放对应资源,因此析构函数可以定义成虚函数,在删除派生类对象时,会根据指针指向的实际对象类型调用相应的析构函数。

    回答:

    可以,声明为虚析构函数后,通过基类指针删除对象时,会根据指针指向的实际对象类型调用相应的析构函数,从而确保对象中的资源能够正确释放。

    08.对象访问普通函数快还是虚函数快?

    回答:

    如果是普通对象的访问,那么访问两者的速度是一样快的;如果是指针或引用对象,则访问普通函数更快,因为此时构成多态,访问虚函数需要先到虚函数列表中去查找对应的虚函数指针,才能访问到虚函数。

    09.虚函数表是在什么阶段生成的,存在哪的?

    回答:

    虚函数表在编译阶段生成,一般情况下存在代码段(常量区)

    10.什么是菱形继承、虚继承?

    回答:

    菱形继承是指一个派生类同时继承自两个间接基类,而这两个基类由继承自同一个共同的基类,形成了一种菱形的继承结构。

    虚继承是为了解决菱形继承的二义性问题而引入的机制,通过在派生类堆共同基类的继承前面加上‘virtual’关键字,使得共同基类在派生类中只保留一份实例,从而避免二义性。

    11.什么是抽象类?抽象类的作用?

    回答:

    抽象类是一种不能被实例化的类,其中至少包含一个纯虚函数,即函数声明末尾有 ‘= 0’ 的函数,用于定义派生类必须实现的接口,抽象类规范了派生类必须重写,实现多态性,另外抽象类更体现了接口继承。

  • 相关阅读:
    linux单机部署kafka
    GITEE 基于OAuth2的API V5版本
    一元线性回归(自写梯度下降法与scikit-learn)
    java路线
    蓝桥杯练习题——多路并归
    坐标正反算(含高程),把要素内置化(无需改程序文件,即可更换路线,同时存两条线要素
    使用vue扫描扫描仪图像
    算法leetcode|12. 整数转罗马数字(rust重拳出击)
    达梦8 在CentOS 系统下静默安装
    如何借助自动化工具落地DevOps|含低代码与DevOps应用实践
  • 原文地址:https://blog.csdn.net/dhgiuyawhiudwqha/article/details/140440252