根据我的理解,VTable是调用函数派生函数最多的必要条件。它将有关于函数的最派生版本的条目...我的疑问是为什么我们需要为基类提供VTable。由于使用基础对象进行调用总是需要调用基类函数。
答案 0 :(得分:1)
由于R Shau不喜欢我的编辑,我基于他提供了我的答案。
VTable是一种处理多态的方法。虽然VTable是C ++编译器广泛使用的一种技术,但它们可以自由地提供任何其他解决方案。
当基类具有一个或多个virtual
成员函数时,基类构造函数将VTable分配给对象。
基类构造函数无法知道正在构造的实对象是基类对象还是派生类对象,因此基对象必须保持指向有效VTable的指针。
示例:
struct Base
{
Base() {}
virtual void m() {}
virtual ~Base() {}
};
struct Derived : public Base
{
Derived() : Base() {}
void m() {}
~Derived() {}
};
void foo()
{
Base b;
Derived d;
Base * bPtr;
}
bPtr
可能指向Base
bPtr = & b;
bPtr->m();
或Derived
bPtr = & d;
bPtr->m();
由于bPtr
属于Base *
类型,如何执行多态调用bPtr->m()
,如果Base::m()
指向{{1},则应调用bPtr
如果b
指向Derived::m()
,则会{}和bPtr
答:在VTable中查找d
方法的地址。
解析m()
时会发生什么:
bPtr->m()
因此,如果没有基类中的VTable,则无法执行多态调用,因为在运行时不知道 bPtr pointing to Base object
bPtr-> vtable_pointer -> VTable of Base -> m() -> points to address of Base::m()
bPtr pointing to Derived object
bPtr-> vtable_pointer -> VTable of Derived -> m() -> points to address of Derived::m()
指向的对象是否真的是基类对象或派生类对象。
答案 1 :(得分:0)
当基类具有一个或多个virtual
成员函数时,基类构造函数将VTable分配给对象。
基类构造函数无法知道正在构造的实对象是基类对象还是派生类对象。
示例:
struct Base
{
Base() {}
virtual ~Base() {}
};
struct Derived : public Base
{
Derived() : Base() {}
~Derived() {}
};
void foo()
{
Base b;
Derived d;
}
直接在行中调用 Base::Base()
Base b;
通过行
中的Derived::Derived()
间接调用它
Derived d;
Base
的实施如何知道Base::Base()
是直接调用Base
还是间接调用Derived
?没有这些知识,就必须确保它的行为对两者都有效 - 这意味着为它们设置VTable。