前言
在讨论多态的语法层面(如虚函数、override、final)之后,很多开发者对底层的运行机制仍有疑问。为什么带虚函数的类 sizeof 会变大?基类指针如何找到派生类的函数?虚表究竟存在哪里?本文将从内存布局、对象模型及汇编视角,彻底讲透 C++ 多态的底层机制。
虚函数与普通函数的区别
通过一个简单的测试可以观察差异:
#include <iostream>
using namespace std;
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;
}
对于普通类,成员函数不占用对象内存。但上述代码在 32 位环境下运行结果为 12,而非预期的 8(1+5 对齐后)。这是因为编译器为含有虚函数的类对象插入了一个虚函数表指针(vptr)。这个指针指向该类的虚函数表(vtable),表中存放了所有虚函数的地址。
多态的实现原理
动态绑定与静态绑定
普通函数调用是编译时确定地址(静态绑定),而满足多态条件(基类指针/引用 + 虚函数)的调用则是运行时根据对象实际类型查找虚表地址(动态绑定)。
例如:
class Person {
public:
virtual void BuyTicket() { cout << "买票 - 全价" << endl; }
private:
string _name;
};
class Student : public Person {
:
{ cout << << endl; }
:
string _id;
};
{
ptr->();
}


