C++中的虚函数表
2024-08-28 22:43:15
(感谢http://blog.csdn.net/haoel/article/details/1948051/)
C++中的虚函数的作用主要是实现了多态的机制。
多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。
虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的,简称为V-Table。在这个表中记录了一个类的虚函数的地址表,这张表解决了继承、覆盖的问题。C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置,所以当我们用父类的指针来操作一个子类的时候,这张虚函数表就像一个地图一样,指明了实际所应该调用的函数。
假设有这样一个基类:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
在虚函数表的最后有一个结点,这是虚函数表的结束结点,就像字符串的结束符“/0”一样,标志了虚函数表的结束。
typedef void(*Fun)(void);
Base b;
Fun pFun = NULL; cout << "虚函数表地址:" << (int*)(&b) << endl;
cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl; // Invoke the first virtual function
pFun = (Fun)*((int*)*(int*)(&b));
pFun(); (Fun)*((int*)*(int*)(&b)+); // Base::f()
(Fun)*((int*)*(int*)(&b)+); // Base::g()
(Fun)*((int*)*(int*)(&b)+); // Base::h()
可以通过强行把&b转成int *,取得虚函数表的地址,然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f()。
一般继承(无虚函数覆盖)
子类没有重载任何父类的函数。对于实例Derive d的虚函数表如下:
1)虚函数按照其声明顺序放于表中。
2)父类的虚函数在子类的虚函数前面。
一般继承(有虚函数覆盖)
如果子类中有虚函数重载了父类的虚函数。
1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。
2)没有被覆盖的函数依旧。
最新文章
- JavaScript知识 一、JS的数据类型
- 导入CSV格式的数据
- c语言 动态数组
- 关于2000W数据
- C# 之 Stream 和 byte[] 的相关转换
- iOS获取webview高度
- RedHat9通过Host-only配置网络连接
- 9年经验,总结SEO职业瓶颈
- javascript 学习资料网址一览
- 请教<;context:component-scan/>;和<;mvc:annotation-driven/>;的区别20
- php中的XML转数组
- 8Manage:聚焦研发企业利器——研发项目管理
- 创建一个 Spring Boot 项目,你会几种方法?
- 译注(2): How to Write a 21st Century Proof
- 信用卡欺诈数据的分析-excel篇
- flink引出的kafka不同版本的兼容性
- day 7-6 GIL,死锁,递归锁与信号量,Event,queue,
- ansible和python的zabbix_api批量添加rsync服务的监控
- SpringBoot(2) Json框架 -- Jackson返回结果处理
- Java知多少(28)super关键字