虚函数-静态绑定-动态绑定
- 如果类中定义了虚函数,那么编译阶段,编译器会给这个类类型产生一个唯一的vftable虚函数表,其中主要存储的是RTTI指针和虚函数的地址。程序运行时,每一张虚函数表都会加载到内存的.rodata只读数据区。
- 一个类中定义了虚函数,那么这个类的对象,其运行时,内存中开始部分,会多存储第一个vfptr虚函数指针,指向相应类型的虚函数表vftable。一个类型定义的n个对象,他们的vfptr指向的都是同一个虚函数表。
- 一个类里面虚函数的个数,不影响对象的内存大小(vfptr),只影响虚函数表的大小。
- 如果派生类中的方法,和基类继承来的某个方法,返回值、函数名、参数列表都相同,而且基类的方法是virtual虚函数,那么派生类的这个方法,自动处理成虚函数。重写<=>覆盖。因此,覆盖指的是虚函数表中虚函数地址被新的重写的虚函数覆盖。
- 总而言之,虚函数表指针存在的意义:一个父类指针指向的究竟是什么类的对象?这个动态信息被存储在虚表指针

class A {
public:
virtual void vfunc1();
virtual void vfunc2();
void func1();
void func2();
private:
int m_data1, m_data2;
};
class B : public A {
public:
void vfunc1();
void func1();
private:
int m_data3;
};
class C: public B {
public:
void vfunc2();
void func2();
private:
int m_data1, m_data4;
};

#include<iostream>
#include<typeinfo>
using namespace std;
#if 0
class Base
{
public:
Base(int data = 10) : ma(data) {}
void show() { cout << "Base::show()" << endl; }
void show(int) { cout << "Base:show(int)" << endl; }
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data = 20) : Base(data), mb(data) {}
void show() { cout << "Derive::show()" << endl; }
private:
int mb;
};
int main()
{
Derive d(50);
Base* pb = &d;
pb->show();
pb->show(10);
cout << sizeof(Base) << endl;
cout << sizeof(Derive) << endl;
cout << typeid(pb).name() << endl;
cout << typeid(*pb).name() << endl;
return 0;
}
#endif
# if 1
class Base
{
public:
Base(int data = 10) : ma(data) {}
virtual void show() { cout << "Base::show()" << endl; }
virtual void show(int) { cout << "Base:show(int)" << endl; }
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data = 20) : Base(data), mb(data) {}
void show() { cout << "Derive::show()" << endl; }
private:
int mb;
};
int main()
{
Derive d(50);
Base* pb = &d;
pb->show();
pb->show(10);
cout << sizeof(Base) << endl;
cout << sizeof(Derive) << endl;
cout << typeid(pb).name() << endl;
cout << typeid(*pb).name() << endl;
return 0;
}
#endif
虚函数的权限问题
class Base
{
public:
Base()
{
cout << "call Base()" << endl;
}
virtual void show()
{
cout << "call Base::show()" << endl;
}
};
class Derive : public Base
{
public:
Derive()
{
cout << "call Derive()" << endl;
}
private:
void show()
{
cout << "call Derive::show()" << endl;
}
};
int main()
{
Base* pb1 = new Derive();
pb1->show();
delete pb1;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报