【C++:继承和多态】多态加餐:面试常考——多态的常见问题11问

🔥艾莉丝努力练剑:个人主页
❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬艾莉丝的简介:

🎬艾莉丝的C++专栏简介:
目录
C++的两个参考文档
本期内容前瞻
1 ~> 什么是多态?
2 ~> 什么是重载、重写(覆盖)、重定义(隐藏)?
3 ~> 多态的实现原理?
4 ~> inline函数可以是虚函数吗?
4.1 参考回答
4.2 补充
5 ~> 静态成员函数可以是虚函数吗?
5.1 参考回答
5.2 补充
6 ~> 构造函数可以是虚函数吗?
6.1 参考回答
6.2 补充
7 ~> 析构函数可以是虚函数吗?什么场景下析构函数是虚函数?
7.1 参考回答
7.2 补充
8 ~> 对象访问普通函数快还是虚函数快?
8.1 参考回答
8.2 补充
9 ~> 虚函数表是在什么阶段生成的,存在哪的?
9.1 参考回答
9.2 补充
10 ~> C++菱形继承的问题?虚继承的原理?
10.1 C++菱形继承的问题
10.2 虚继承的原理
10.3 补充
11 ~> 什么是抽象类?抽象类的作用?
11.1 参考回答
11.2 补充
本文博主手记
结尾
C++的两个参考文档
老朋友(非官方文档):cplusplus
官方文档(同步更新):cppreference
本期内容前瞻

1 ~> 什么是多态?

2 ~> 什么是重载、重写(覆盖)、重定义(隐藏)?

3 ~> 多态的实现原理?
不要光答虚表两个字——这只是一层,说全一点:父类有虚函数后、有虚表,子类 也有虚表。如果有多个子类,每个子类都各自有虚表。

运行时不是说编译时确定调用谁,而是一个父类的指针调用这个函数,到底调用谁,不一定调父类的,要看指向哪个对象。因为是到指针或者引用指向的对象的虚函数表里去,所以才达到了指向谁就调用谁的效果。
4 ~> inline函数可以是虚函数吗?
4.1 参考回答
答:可以,不过编译器忽略inline属性,这个函数就不再具有inline属性,因为虚函数要放到虚表中去,也就是说inline属性和虚函数属性是不能同时存在的。
4.2 补充
语法上不报错,但是至少说明作为多态调用时到虚表里去找的时候,inline函数的内联属性就丢了——正常函数的调用是call地址,跳转过去调用;内联的特点:跳转过去调用,要建立栈帧,内联就不需要地址,因为内联就是调用那个符合内联属性的函数把内联展开,(当然要符合内联要求:内联要求比较短小)所以没有地址,如果这个是虚函数,虚函数必然是要有地址放进虚表里去走——如果要走多态这条路径调用的话,必然是call一个地址,找到虚表里面——看前面多态,“指向谁调用谁”——虚函数还能是内联吗?因此两个属性不能同时存在。
为什么语法编译上又能同时存在?
虚函数也不一定是多态调用。

5 ~> 静态成员函数可以是虚函数吗?
5.1 参考回答
答:不能,因为静态成员函数没有this的指针,使用类型::成品函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。
5.2 补充

6 ~> 构造函数可以是虚函数吗?
6.1 参考回答
答:不能,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。
6.2 补充
要去指向对象的虚表里去找,怎么找?对象还没有初始化完成。
7 ~> 析构函数可以是虚函数吗?什么场景下析构函数是虚函数?
7.1 参考回答
答:可以,并且最好是把基类的析构函数定义成虚函数。
7.2 补充
跟构造函数不一样,析构函数我们建议是虚函数——父类指针可能指向父亲对象也可能指向子类对象,要调用对应的析构函数,指向父类调父类,指向子类调子类,把析构函数实现成虚函数,让调用析构函数那一步变成多态调用才能符合。
8 ~> 对象访问普通函数快还是虚函数快?
8.1 参考回答
答:首先如果是普通对象调用,是一样快的。如果是指针或者引用去调用,则普通函数调用快,因为构成多态,运行时定义虚函数需要到虚函数表里面去查找。
8.2 补充

虚函数和普通函数都是放在代码段区域,都要call去调用,不同的是虚函数的指针会放到虚表——多态的那块逻辑,但虚函数的指针会放到~>如果不是作为多态调用就跟普通函数是一样的,会很快;如果作为多态调用会慢一点点(普通调用是直接call地址,多态调用要先找到虚表的指针,再去虚表那里找到对应虚函数,然后再call)。
9 ~> 虚函数表是在什么阶段生成的,存在哪的?
9.1 参考回答
答:虚函数是在编译阶段就生成的;一般情况下存在代码段(常量区)。
9.2 补充

10 ~> C++菱形继承的问题?虚继承的原理?
10.1 C++菱形继承的问题

10.2 虚继承的原理

10.3 补充
注意:不要把虚函数和虚基表搞混了。
11 ~> 什么是抽象类?抽象类的作用?
11.1 参考回答
答:不能实例化对象(没啥意义),包含纯虚函数,(某种程度上来说)抽象类强制重写了虚函数,另外抽象类体现了接口继承关系。
11.2 补充

本文博主手记



结尾
往期回顾:
【C++:继承】面向对象编程精要:C++继承机制深度解析与最佳实践
【C++:继承】C++面向对象继承全面解析:派生类构造、多继承、菱形虚拟继承与设计模式实践
【C++:多态】深入剖析C++多态精髓:虚函数机制、重写规范与现代C++多态控制
结语:都看到这里啦!那请大佬不要忘记给博主来个“一键四连”哦!
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡
૮₍ ˶ ˊ ᴥ ˋ˶₎ა

