创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
c语言内容💖:
专栏:c语言之路重点知识整合
【c语言】全部知识点总结
目录
- 一、虚函数的调用流程
- 模仿_vfptr手动实现多态
- 二、虚函数和一般函数的区别
一、虚函数的调用流程
在定义了虚函数的类中,类的最开始部分是一个虚函数表的指针——虚函数指针
虚函数指向一个虚函数表,表中存放了虚函数的地址,实际的虚函数存放在代码段中。
当子类继承了父类的时候也会继承父类的虚函数表,当子类重写父类中虚函数的时候,会将继承到虚函数表中的地址替换为重写的函数地址。这个过程称为覆盖
虚函数列表中,在重写虚函数的后面是父类未重写的虚函数,然后是子类虚函数
以上的过程将在编译阶段进行
_vfptr
指向虚函数列表,通过对虚函数列表中的函数取址执行就能实现多态
模仿_vfptr手动实现多态
在类中定义两个虚函数:
class CTest
{
public:
virtual void fun(){ cout << "virtual void fun()" << endl; }
virtual void fun2() { cout << "virtual void fun2()" << endl; }
};
在主函数中定义一个对象,并定义一个父类指针指向这个对象
CTest tst;
CTest* ptst = nullptr;
ptst = &tst;
首先实现虚函数指针的描述:
由于虚函数指针vfptr
处于对象的内存最前面,并且占用4字节
通过解引用取得对象内存首地址的vfptr
*(int*)ptst
通过vfptr指针
间接引用到虚函数列表vftable
将 ptst 所指向的内存中的值视为一个整数
(int*) (*(int*)ptst) [0]
再视为一个指向函数的指针,赋值给 p_fun1
typedef void (*P_FUN)();
P_FUN p_fun1 = (P_FUN)((int*)(*(int*)&tst))[0];
完整调用流程:
typedef void (*P_FUN)();
P_FUN p_fun1 = (P_FUN)((int*)(*(int*)&tst))[0];
P_FUN p_fun2 = (P_FUN)((int*)(*(int*)&tst))[1];
(*p_fun1)();
(*p_fun2)();
二、虚函数和一般函数的区别
- 调用流程不同:虚函数通过虚函数指针间接引用,普通函数可以使用函数名直接调用
- 调用效率不同:虚函数调用流程复杂,效率低,普通函数效率高
- 使用场景不同:虚函数的目的是为了实现多态
使用了虚函数,会增加访问内存开销,降低效率。
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |