C ++,为什么Base类需要一个VTable

时间:2015-01-05 04:07:11

标签: c++ virtual vtable

根据我的理解,VTable是调用函数派生函数最多的必要条件。它将有关于函数的最派生版本的条目...我的疑问是为什么我们需要为基类提供VTable。由于使用基础对象进行调用总是需要调用基类函数。

2 个答案:

答案 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。

相关问题