2014-04-04 76 views
1

第一个: 我在某处读到虚拟函数的机制是未定义的。即这意味着每个编译器都可以以不同方式推进。但是,我发现的关于虚函数mechanisn的每一篇文章都谈到了VTBL和VPTR。虚拟函数机制实现

是否还有其他的虚拟功能机制实现?你能举一些例子吗?

second: 不同语言的VTBL实现有什么区别?

回答

0

我会告诉你一个例子。

class B 
{ 
private: 
    int m_i; 
public: 
    void foo() { puts("B::foo"); } 
    virtual void bar() { puts("B::bar"); } 
}; 
class D : public B 
{ 
private: 
    int m_j; 
public: 
    virtual void bar() { puts("D::bar"); } 
    virtual void asdf() { puts("D::asdf"); } 
}; 

int main() 
{ 
    D d; 
    B *pb = &d; 
    pb->bar(); 
} 

大多数编译器实现了代码如下:

struct B; 
struct __vtbl_B_t 
{ 
    void (*bar)(B * const this); 
}; 
struct B 
{ 
    const __vtbl_B_t *__vptr; 
    int m_i; 
}; 
void B__foo(B * const this) { puts("B::foo"); } 
void B__bar(B * const this) { puts("B::bar"); } 

const __vtbl_B_t __vtbl_B = { B__bar }; 
void B__ctor(B * const this) 
{ 
    this->__vptr = &__vtbl_B; 
} 

struct D; 
struct __vtbl_D_t 
{ 
    __vtbl_B_t __base; 
    void (*asdf)(D * const this); 
}; 
struct D 
{ 
    B __base; 
    int m_j; 
}; 
void D__bar(D * const this) { puts("D::bar"); } 
void D__asdf(D * const this) { puts("D::asdf"); } 

__vtbl_D_t __vtbl_D = { { (void (*)(B * const))D__bar }, D__asdf }; 
void D__ctor(D * const this) 
{ 
    B__ctor((B * const)this); 
    this->__base.__vptr = (const __vtbl_B_t *)&__vtbl_D; 
} 

int main() 
{ 
    D d; 
    D__ctor(&d); 

    B *pb = (B *)&d; 

    (*pb->__vptr->bar)(pb); 
} 

输出:

D::bar 

即使你的语言不是C++,编译器的行为是similiar。

1

一个受欢迎的选择是inline caching,我认为它来自于Smalltalk系统。

另一种选择是每个多态方法都有一个类型表,而不是每个类型都有一个多态方法表(VMT)。它需要完整的程序分析,但可以实现高效的多重继承。一些Eiffel编译器使用这种方法(more here,寻找“如何有效地实现多重继承?”)。

最后一个也提到了另一种方法,一个基于switch语句的方法(检查C中的Eiffel〜switch)。 SmartEiffel使用它的变体,它根据类ID进行二进制搜索。它还需要进行全面的程序分析,但由于更好的指令缓存行为,有时在当前系统上可能比VMT更有效。 (more here,查找“无虚拟函数表的高效动态分派”)。