AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
# 深入了解C++虚指针 ## 什么是虚函数表 指针大小是固定的,无论该指针指向哪种数据类型,32位机为4个字节,64位机为8个字节。 C++标准规定,凡是一个独立的(非附属)对象都必须具有非零大小,即C++空类大小不能为0。验证空类大小为1。 ![](https://img.kancloud.cn/75/84/758437eb126980d1bd85b92c4d47131c_400x223.png) 虚函数表: 在64位机中,如果类中存在虚函数,那么该类的大小就会多8个字节,然而这8个字节就是一个指针的大小,这个指针指向虚函数表。所以,如果对象存在虚函数,那么编译器就会生成一个指向虚函数的指针,所有的虚函数都存在于这个表中,虚函数表就可以理解为一个数组,每个单元用来存放虚函数的地址。下面来测试验证: ~~~ #include <iostream> ​ using namespace std; ​ class foo1 { }; ​ class foo2 {    void f(); }; ​ class foo3 {    virtual void f(); }; ​ class foo4 {    int a; }; ​ class foo5 {    int a;    void f(); }; ​ class foo6 {    int a;    virtual void f(); }; ​ class foo7 {    int a;    int b;    virtual void f(); }; ​ int main() {    cout << "sizeof(foo1)=" << sizeof(foo1) << endl;    cout << "sizeof(foo2)=" << sizeof(foo2) << endl;    cout << "sizeof(foo3)=" << sizeof(foo3) << endl;    cout << "sizeof(foo4)=" << sizeof(foo4) << endl;    cout << "sizeof(foo5)=" << sizeof(foo5) << endl;    cout << "sizeof(foo6)=" << sizeof(foo6) << endl;    cout << "sizeof(foo7)=" << sizeof(foo7) << endl;    return 0; } ~~~ 输出结果 ~~~ sizeof(foo1)=1 sizeof(foo2)=1 sizeof(foo3)=8 sizeof(foo4)=4 sizeof(foo5)=4 sizeof(foo6)=16 sizeof(foo7)=16 ~~~ 以上结果明显,普通成员函数不占空间大小,如果类中加入一个虚函数,则整个类的大小增加8个字节(一个指针大小)。foo3增加7个字节大小是要减去空类规定的大小1。foo6增加12个字节大小,是因为增加一个虚函数指针8个字节,后面成员变量大小为4,和前面字节对齐,则总大小为16,foo7验证是对的。 虚函数: 虚函数是通过一张虚函数表来实现的,简称V-Table。这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的指针的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要了,它就像一个地图一样,指向了实际所应该调用的函数。