前言
在多态核心语法层面(虚函数、重写、纯虚函数等)的基础上,多态的底层依赖于 vptr 虚指针与 vtable 虚函数表。学习时常有以下疑问:带虚函数的类 sizeof 为何多出字节?基类指针指向不同派生类对象如何找到对应函数?虚表、虚指针存在内存哪个区域?静态绑定和动态绑定的区别?本篇从内存布局、对象模型、汇编视角出发,彻底讲透 C++ 多态底层原理。
正文
一、虚函数和普通函数的区别
对于普通类,成员函数所占内存总和在对齐后即为类内存大小。但带有虚函数的类,sizeof 会多出 4/8 字节(取决于系统位数)。这是因为对象中包含了一个虚函数表指针(vptr)。一个含有虚函数的类至少都有一个虚函数表指针,所有虚函数的地址被放到该类的虚函数表(vtable)中。
二、多态的原理
多态是如何实现的
满足多态条件后,底层不再是编译时通过调用对象确定函数地址,而是运行时到指向对象的虚表中确定对应的虚函数地址。这样实现了指针或引用指向基类就调用基类的虚函数,指向派生类就调用派生类对应的虚函数。
class Person {
public:
virtual void BuyTicket() { cout << "买票 - 全价" << endl; }
private:
string _name;
};
class Student : public Person {
public:
virtual void BuyTicket() { cout << "买票 - 打折" << endl; }
private:
string _id;
};
class Soldier : public Person {
public:
virtual void BuyTicket() { cout << "买票 - 优先" << endl; }
private:
string _codename;
};
void Func(Person* ptr) {
// 这里可以看到虽然都是 Person 指针 Ptr 在调用 BuyTicket
// 但是跟 ptr 没关系,而由 ptr 指向的对象决定的。
ptr->BuyTicket();
}
{
Person ps;
Student st;
Soldier sr;
(&ps);
(&st);
(&sr);
;
}


