6月1日 10:30

C++ 多态怎么实现?vtable/vptr 与动态绑定原理详解

C++ 多态分编译时和运行时两种。编译时多态通过函数重载和模板实现,编译器根据参数类型或模板实参在编译期确定调用目标,零运行开销。运行时多态依赖虚函数机制:每个含虚函数的类拥有一张虚函数表(vtable),存储各虚函数的入口地址;每个对象实例持有指向所属类 vtable 的虚指针(vptr)。调用虚函数时,通过 vptr 查 vtable 完成动态绑定,实现了根据实际对象类型调用对应版本。纯虚函数使类成为抽象类,强制子类必须实现。析构函数声明为虚函数可确保 delete 基类指针时正确调用派生类析构,避免资源泄漏。多重继承下对象可能包含多个 vptr,分别指向不同基类的 vtable。

追问

vtable 存在哪里?每个对象都有独立的 vtable 吗?

vtable 通常在编译期生成,存于只读数据段。同一类的所有对象共享同一张 vtable,各对象只存一个 vptr 指向它。

构造函数可以是虚函数吗?

不能。构造时对象类型尚未完整,vptr 还未初始化完成,虚函数机制尚未就绪,无法进行动态绑定。

虚函数调用一定有运行开销吗?

大多数情况有一次间接寻址开销。但编译器若能在调用点确定实际类型(如通过 final 类或显式限定),会进行去虚化(devirtualization)优化为直接调用。

多重继承下 vptr 怎么布局?

对象按继承顺序排列各基类子对象,每个有虚函数的基类子对象各有一个 vptr。通过不同基类指针访问时,指针值可能需要偏移调整(this adjustment)。

标签:C++