我有一个带有 1 个虚函数的基类
class Base
{
public:
virtual void print() {
cout<<"IN BASE\n";
}
}
现在我使用创建它的对象
Base b
和呼叫
b.print();
这是动态绑定吗,因为“基”类包含 1 个虚函数并创建了它的 VTable。
我有一个带有 1 个虚函数的基类
class Base
{
public:
virtual void print() {
cout<<"IN BASE\n";
}
}
现在我使用创建它的对象
Base b
和呼叫
b.print();
这是动态绑定吗,因为“基”类包含 1 个虚函数并创建了它的 VTable。
在创建对象的同一上下文中,编译器不需要使用虚拟调度,因为它知道确切的类型。但这与虚函数的数量无关(是的,只要至少有一个,编译器就会生成一个vtable并将vptr存储在您的对象中)。
Base b;
b.print(); // can be optimized to b.Base::print(),
// with no virtual dispatch
void f( Base& b ) {
b.print(); // must use virtual dispatch (ignoring potential inlining)
}
术语“动态绑定”通常意味着其他东西 - 允许您从外部文件(DLL 或 SO)调用函数的管道,就好像它们是可执行文件的一部分一样。
该类Base
有一个 vtable 是正确的 - 毕竟,在编译当前文件时,编译器无法确定在项目的其他地方是否有它的任何派生类。
现在,调用是否遵循 vtable 是一个实现细节——它取决于编译器和设置。一方面,它应该。另一方面,如果对象像这样是自动的,那么它的类型在编译时是已知的,并且不可能是Base
. 一个好的编译器可能会优化 vtable 查找。
启用装配列表的构建肯定会向您展示。