C++中final修饰虚函数是否无多态?编译器能否省略虚表优化?
关于final虚函数与多态、编译器优化的问题
先看给定的类结构:
struct base { virtual void f () const = 0; }; struct derived : public base { virtual void f () const final { // ... } };
1. 是否可认为不存在多态?
不能这么说。虽然f()只有一个实现且被final禁止重写,但多态的潜在场景依然存在——只要代码里有用基类base的指针或引用指向derived对象的情况,就属于多态调用的语法范畴。比如:
derived d; const base& b_ref = d; b_ref.f(); // 这里语法上是多态调用,哪怕只有一个实现
final的作用只是阻止后续子类重写f(),但并没有消除基类虚函数带来的多态可能性。
2. 编译器是否会遵循“不使用则不付出”原则,避免使用虚表?
这取决于实际的代码使用场景:
- 如果代码里从来没有通过基类指针/引用调用
f(),编译器完全可以优化掉虚表。比如直接创建derived对象调用f(),编译器会直接做静态调用,不需要虚表支持,符合零成本抽象的原则。 - 如果代码里存在基类指针/引用调用
f()的情况,编译器通常会保留虚表,但可能会做针对性优化:比如在能明确推导指针/引用实际指向derived对象的情况下,把虚调用直接优化为静态调用(也就是“去虚拟化”)。不过这种优化不是绝对的,要看编译器的能力和代码的可推导程度。
内容的提问来源于stack exchange,提问作者Flupke
相关产品推荐
相关产品推荐

