前言
多态真正落到机器层面,靠的不是语法糖,而是 vptr 虚指针和 vtable 虚函数表。很多人第一次学这块都会卡在几个点上:为什么带虚函数的类 sizeof 会变大、基类指针怎么在运行时找到派生类实现、虚表和虚指针到底放在哪、静态绑定和动态绑定差在哪。把这些问题串起来看,C++ 多态就没那么玄乎了。
虚函数和普通函数的区别
普通类里,成员函数不计入对象大小,对象的内存占用主要由成员变量和对齐决定。可一旦类里出现虚函数,对象里通常会多出一个虚函数表指针 vptr,在 32 位环境下常见是 4 字节,64 位环境下常见是 8 字节。这个指针指向当前类型对应的虚函数表。
虚函数本身并不'住'在对象里。它和普通函数一样,编译后都是代码段里的函数入口,只是这些入口地址会被收进虚表。
多态是怎么工作的
C++ 的运行时多态,关键在'通过基类指针或引用调用虚函数'这个前提上。编译器不会在编译期把调用目标彻底定死,而是先从对象里取出 vptr,再顺着虚表找到对应函数地址,最后完成调用。对象实际是谁,调用的就是谁的实现。
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) {
// 这里调用的是 ptr 指向对象实际类型对应的 BuyTicket
ptr->BuyTicket();
}
{
Person ps;
Student st;
Soldier sr;
(&ps);
(&st);
(&sr);
;
}


