C++ 多态底层实现机制深度解析
在之前的讨论中,我们初步了解了虚函数、重写、纯虚函数等语法层面的知识。但很多同学在深入理解时仍会有疑问:为什么带虚函数的类 sizeof 会变大?基类指针指向不同派生类对象时,运行时如何找到对应函数?虚表、虚指针到底存在内存的哪个区域?
本文将从内存布局、对象模型及汇编视角出发,彻底讲透 C++ 多态的底层原理。
虚函数与普通函数的区别
我们可以通过一个简单的例子来观察内存差异。
class Base {
public:
virtual void Func1() { cout << "Func1()" << endl; }
protected:
int _b = 1;
char _ch = 'x';
};
int main() {
Base b;
cout << sizeof(b) << endl;
return 0;
}
对于普通类,成员函数不占用对象内存空间。理论上 _b (4 字节) + _ch (1 字节) 经过内存对齐后应为 8 字节。但实际运行结果是 12 字节。
这是因为编译器在含有虚函数的类对象中隐藏添加了一个指针,称为虚函数表指针(vptr)。一个含有虚函数的类至少包含一个 vptr,它指向该类的虚函数表(vtable)。

多态的实现原理
动态绑定与静态绑定
多态的核心在于动态绑定。当满足多态条件(指针或引用 + 调用虚函数)时,编译器不会在编译期确定函数地址,而是生成代码让程序在运行时通过对象的 vptr 找到对应的虚表,再从虚表中获取函数地址进行调用。
如果不满足多态条件(如直接调用非虚函数),则发生静态绑定,编译器直接在编译期确定函数地址。
class Person {
public:
virtual void BuyTicket { cout << << endl; }
:
string _name;
};
: Person {
:
{ cout << << endl; }
:
string _id;
};
: Person {
:
{ cout << << endl; }
:
string _codename;
};
{
ptr->();
}
{
Person ps;
Student st;
Soldier sr;
(&ps);
(&st);
(&sr);
;
}



