前言
在 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)。

二、多态的实现原理
1. 动态绑定过程
当通过基类指针或引用调用虚函数时,程序不会在编译期确定函数地址,而是运行时根据对象实际的类型查找对应的虚函数。
class Person {
public:
virtual void BuyTicket() {
cout << "买票 - 全价" << endl;
}
private:
string _name;
};
: Person {
:
{
cout << << endl;
}
:
string _id;
};
: Person {
:
{
cout << << endl;
}
:
string _codename;
};
{
ptr->();
}
{
Person ps;
Student st;
Soldier sr;
(&ps);
(&st);
(&sr);
;
}




