【C++】多态问答题

前言

本篇仅整理一些比较偏的多态的问答题

在这里插入图片描述

一. 内联与虚函数

内联函数可以是虚函数吗?
首先我们看一下语法有没有问题
在这里插入图片描述

我们看到,程序成功运行了,语法也没有报错。好像没问题
但是,内联函数时不能成为虚函数的!

首先,内联关键字inline是对编译器的一种建议,具体该函数能否成为内联函数,还要看编译器。
而一个函数成为内联函数,那他就会像宏一样,直接在调用的地方展开,所以不需要函数地址
而虚函数是需要函数有地址的,因为需要将指向该函数的函数指针放到虚表里。
所以内联函数和虚函数是相矛盾的,二者不可兼得
这里之所以没有崩溃,是编译器认为该函数时虚函数了,就不会让他成为内联函数
在这里插入图片描述

PS:内联函数不可以是虚函数,但是inline修饰的函数可以是虚函数。这里要注意以下问法

二. 静态函数与虚函数

静态成员函数可以是虚函数吗?
答案是不可以

  1. 首先以使用的角度,静态成员变量或者静态成员函数并不是单独属于某个对象,和实现多态的目的没有关系,多态就是要让不同对象有不同的结果。
  2. 其次,静态成员函数没有this指针,使用类型::成员函数的调用方式,无法访问虚函数表,所以静态成员函数无法放到虚表里

三. 构造函数与虚函数

构造函数可以是虚函数吗?
答案是不可以
因为虚函数的地址是要进虚表的,虚表是在编译时形成的,没问题,但是虚表指针是在初始化列表形成的。
如果将构造函数设置成虚函数,那调用构造函数要虚表指针,但是虚表指针要在构造函数的初始化列表生成,就找不到虚表。成了一个死循环。

扩展:拷贝构造也不可以设置成虚函数,原理和构造函数一样。
在这里插入图片描述

但是赋值重载可以设置成虚函数,语法并没有报错
但是不建议,因为子类的赋值重载本身就需要调用父类的赋值重载,父类部分交给父类,子类部分交给子类,那你重写了赋值重载,那不就找不到父类的赋值重载了吗。

四. 虚函数与普通函数

虚函数和普通函数的效率谁更高
答案是不一定

虚函数其实并不是一定去虚表里找函数地址。
除内联函数,每个函数都有都有函数地址,而一个类有虚函数,则会有虚表,会有指向虚函数的函数指针存储在虚表中。
而如果是普通对象调用虚函数,其实是直接调用函数地址,并不会进入虚表
而当是指针或引用时,才会进入虚表找函数地址

结束语

本篇文章是对多态的一些比较偏的知识的笔记,掌握要求不深,感谢您的阅读

如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_72563041/article/details/130043455