接口(只有纯虚函数的多态类)有vtable吗?由于接口本身并不实现多态函数,也不能直接构造,因此链接器不需要放置vtable。是真地吗?我特别关注MSVC编译器。
发布于 2012-06-26 04:01:18
是的,它们确实如此。这其中有很多很好的理由。
第一个很好的原因是,即使是纯虚方法也有实现。隐式或显式。实现一个调用纯虚函数的技巧是相对容易的,所以你基本上可以为你的一个函数提供一个定义,调用它,看看会发生什么。出于这个原因,首先应该有一个虚拟表。
将虚表放入基类还有另一个原因,即使它的所有方法都是纯虚的,并且没有其他数据成员。当使用多态性时,指向基类的指针在整个程序中传递。为了调用虚方法,编译器/运行时应该计算出虚表相对于基指针的相对偏移量。如果C++没有多重继承,可以假设抽象基类的偏移量为零(例如),在这种情况下,那里可能没有vtable (但由于#1的原因,我们仍然需要它)。但是因为涉及到多重继承,所以"vtable在那里的偏移量为0“的技巧不会起作用,因为根据基类的数量(和类型),可能会有两到三个vtable。
可能还有其他我还没有想到的原因。
希望能有所帮助。
发布于 2012-06-26 03:55:17
从纯C++的角度来看,这是一个学术问题。虚函数不一定要用vtable实现,如果是这样,就没有可移植的方法来获取它们。
如果您特别关心MSVC编译器,那么您可能希望使用__declspec(novtable)来装饰您的接口。
(通常,在常见的实现中,抽象类可能需要vtable,例如:
struct Base {
Base();
virtual void f() {}
virtual void g() = 0;
};
void h(Base& b) {
b.f(); // Call f on a Base that is not (yet) a Derived
// vtable for Base required
}
Base::Base() {
h(*this);
}
struct Derived : Base {
void g() {}
};
int main() {
Derived d;
})
发布于 2012-06-26 16:20:32
vtable不是必需的,但很少会优化出来。MSVC提供了__declspec(novtable)扩展,它显式地告诉编译器可以删除vtable。如果没有这样做,编译器将不得不检查自己是否没有使用vtable。这并不是特别困难,但仍然远非微不足道。而且由于它在常规代码中没有提供真正的速度优势,所以我所知道的任何编译器都没有实现该检查。
https://stackoverflow.com/questions/11196329
复制相似问题