最常用的例子来说明为什么虚拟分派发生在运行时是当无法在编译时确定将创建哪个Derived类时。例如:
Base* b = (rand() % 2 == 1 ? new Derived1() : new Derived2());
或者当它依赖于用户输入时。
假设以上情况都不是,并且在编译时可以完全确定基指针所指的派生类。
如果在编译时已知基类指针指向哪个派生类,编译器是否通过替换为适当的派生函数并在运行时不进行虚表查找来优化虚函数调用?
最常用的例子来说明为什么虚拟分派发生在运行时是当无法在编译时确定将创建哪个Derived类时。例如:
Base* b = (rand() % 2 == 1 ? new Derived1() : new Derived2());
或者当它依赖于用户输入时。
假设以上情况都不是,并且在编译时可以完全确定基指针所指的派生类。
如果在编译时已知基类指针指向哪个派生类,编译器是否通过替换为适当的派生函数并在运行时不进行虚表查找来优化虚函数调用?
这种优化被称为去虚拟化(Devirtualization)。至少Clang能够执行这种操作,详见此篇博客文章和此篇邮件列表中的帖子。