C++ 虚拟关键字内部
我听说很多次虚拟函数通常是用vtable实现的。但我实际上不知道它是如何实现的,它是如何工作的 编辑 我实际上没有得到这个代码:如何重写它。有人能详细解释一下吗 最后,让我们看看编译器如何实现对虚拟函数的调用。您的代码可能如下所示:C++ 虚拟关键字内部,c++,C++,我听说很多次虚拟函数通常是用vtable实现的。但我实际上不知道它是如何实现的,它是如何工作的 编辑 我实际上没有得到这个代码:如何重写它。有人能详细解释一下吗 最后,让我们看看编译器如何实现对虚拟函数的调用。您的代码可能如下所示: // Your original C++ code void mycode(Base* p) { p->virt3(); } // Pseudo-code that the compiler generates from your C++
// Your original C++ code
void mycode(Base* p)
{
p->virt3();
}
// Pseudo-code that the compiler generates from your C++
void mycode(Base* p)
{
p->__vptr[3](p);
}
编译器不知道这是调用Base::virt3()
还是Der::virt3()
或者调用另一个甚至不存在的派生类的virt3()
方法。它只能确定您正在调用virt3()
,该函数恰好是v-table的插槽3中的函数。它将调用重写为如下内容:
// Your original C++ code
void mycode(Base* p)
{
p->virt3();
}
// Pseudo-code that the compiler generates from your C++
void mycode(Base* p)
{
p->__vptr[3](p);
}
<关于C++ FAQ的解释很好。你应该读一读。我认为,如果您尝试自己理解它,然后询问您的疑问会更好。常见的实现是在指向vtable的对象的每个实例的开头都有一个指针。每个类有一个vtable,因此如果您有一个类a和类B,那么每个类都有一个表
vtable本质上有一组函数指针,因此如果类a有两个虚拟函数foo()和bar(),那么表将同时有指向这两个函数的指针。如果类B重写了这两个函数,那么它的foo()和bar()版本将具有相同的偏移量。理解vtables如何工作的一个简单方法是使用函数指针在C中实现相同类型的功能,因为vtable就是一个指向具体实现的函数指针表