前言
本篇仅整理一些比较偏的多态的问答题
一. 内联与虚函数
内联函数可以是虚函数吗?
首先我们看一下语法有没有问题
我们看到,程序成功运行了,语法也没有报错。好像没问题
但是,内联函数时不能成为虚函数的!
首先,内联关键字inline是对编译器的一种
建议
,具体该函数能否成为内联函数,还要看编译器。
而一个函数成为内联函数,那他就会像宏一样,直接在调用的地方展开
,所以不需要函数地址
。
而虚函数是需要函数有地址
的,因为需要将指向该函数的函数指针放到虚表
里。
所以内联函数和虚函数是相矛盾
的,二者不可兼得
这里之所以没有崩溃,是编译器认为该函数时虚函数了,就不会让他成为内联函数
PS:内联函数不可以是虚函数,但是inline修饰的函数可以是虚函数
。这里要注意以下问法
二. 静态函数与虚函数
静态成员函数可以是虚函数吗?
答案是不可以
- 首先以使用的角度,静态成员变量或者静态成员函数并不是单独属于某个对象,和实现多态的目的没有关系,多态就是要让不同对象有不同的结果。
- 其次,静态成员函数
没有this指针
,使用类型::成员函数
的调用方式,无法访问虚函数表,所以静态成员函数无法放到虚表里
三. 构造函数与虚函数
构造函数可以是虚函数吗?
答案是不可以
因为虚函数的地址是要进虚表的,虚表是在编译时形成的,没问题,但是虚表指针是在初始化列表形成的。
如果将构造函数设置成虚函数,那调用构造函数要虚表指针,但是虚表指针要在构造函数的初始化列表生成,就找不到虚表。成了一个死循环。
扩展:拷贝构造
也不可以设置成虚函数,原理和构造函数一样。
但是赋值重载
可以设置成虚函数,语法并没有报错
但是不建议
,因为子类的赋值重载本身就需要调用父类的赋值重载
,父类部分交给父类,子类部分交给子类,那你重写
了赋值重载,那不就找不到父类的赋值重载
了吗。
四. 虚函数与普通函数
虚函数和普通函数的效率谁更高
答案是不一定
虚函数其实并不是一定去虚表里找函数地址。
除内联函数,每个函数都有都有函数地址,而一个类有虚函数,则会有虚表,会有指向虚函数的函数指针存储在虚表中。
而如果是普通对象
调用虚函数,其实是直接调用函数地址
,并不会进入虚表
而当是指针或引用时
,才会进入虚表找函数地址
结束语
本篇文章是对多态的一些比较偏的知识的笔记,掌握要求不深,感谢您的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。