2011-08-23 96 views

回答

9

从技术上讲,这是一个实现细节。 C++标准没有提到vtable或vptrs。

但通常,编译器只会在成员函数以多义意义被调用时(即通过指针/参考基类)调用vtable/vptr机制。如果它在编译时知道要做什么,那么就不需要间接方法。

3

仅适用于虚拟函数查找。非虚拟成员函数并不需要太多特殊 - 它只是一个正常函数,它将this作为隐藏参数。

1

该标准并没有规定如何实现继承,所以一个vtable不一定存在。但据我所知,目前所有主要编译器都只使用vtable来调用虚拟函数。

1

dynamic_cast也会使用vtable,我相信。

0

据我所知,只有当被调用的方法被指定为虚拟时,vtable才会被创建(并因此被使用)。如果它是虚拟的,那么它将使用vtable,如果它不是虚拟的,那么它将被静态绑定。

这个确定是在编译时完成的。

-1

和方法指针查找。至少有一个检查指针是否指向虚拟成员函数。

+0

支票?何时执行检查? –

+0

编译器不知道什么是虚拟的,哪些不是虚拟的? –

+0

当一个方法指针被调用时,最后一位被测试:如果它是1,它是一个指向虚方法的指针,否则它是一个指向成员函数的指针。你可以用objdump轻松地检查。你也可以检查成员函数指针的大小,它不仅是一个指针。实际上它是一个偏移+调用方法的vtable中的地址或索引。 – Thomas

0

这始终是实现相关的,但大多数编译器将使用虚函数表时:被称为

  • virtual功能;
  • 当使用dynamic_cast地址的vtables被使用。实际的vtable没有被使用,但它必须存在有一个地址。
  • virtual -y继承的类正在接受。

virtual -y继承类访问包括虚拟和非虚拟方法调用,而且现场访问,甚至指针铸造

class foo{ 
public: 
    virtual void bar(){} 
}; 

class foo2: public virtual foo{ 
public: 
    virtual void bar2(){} 
}; 

int main(int argc, char *argv[]) 
{ 
    foo2* f2= new foo2(); 
    f2->bar(); 
    foo* f1 = f2; 
} 

foo* f1 = f2;线也将读取虚函数表(虽然首先检查会用于f2 == NULL,在这种情况下f1也将为NULL)。

相关问题