编译器是否为所有类都为其创建了Vtable? [英] Do all classes have a Vtable created for them by the compiler?

查看:51
本文介绍了编译器是否为所有类都为其创建了Vtable?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关VTables的在线资源很多.他们通常对他们有相同的陈述:

There are many resources online about VTables. They commonly have the same statement regarding them:

"每当类本身包含虚函数或从父类覆盖虚函数时,编译器都会为该类构建一个vtable.这意味着编译器并非为所有类都为其创建了vtable. vtable包含指向该类中的虚函数的函数指针.每个类只能有一个vtable,并且同一类的所有对象将共享同一vtable."

"Whenever a class itself contains virtual functions or overrides virtual functions from a parent class the compiler builds a vtable for that class. This means that not all classes have a vtable created for them by the compiler. The vtable contains function pointers that point to the virtual functions in that class. There can only be one vtable per class, and all objects of the same class will share the same vtable."

那么,为什么这意味着并非所有类都具有由编译器为其创建的vtable呢?是因为somc类没有虚函数吗?

So why exactly does this mean that not all classes have a vtable created for them by the compiler? Is it because somc classes don't have virtual functions?

推荐答案

精确地.有些类没有vtable,因为它们没有任何虚拟方法.

Precisely. Some classes don't have a vtable because they don't have any virtual methods.

虚拟方法是编译器无法生成直接调用的方法,因为它根据类的实现而有所不同.Vtables是一种查找表,可以通过延迟在程序运行时调用哪个实现的决策来解决此问题:您的编译器不生成函数调用,而是在vtable上生成方法查找,然后调用返回的方法

Virtual methods are methods for which your compiler cannot generate a direct call because it varies depending on the implementation of the class. Vtables are a kind of lookup table that solve this problem by delaying the decision of which implementation to call during the run time of your program: instead of generating a function call, your compiler generates a method lookup on the vtable, then calls the returned method.

以这个例子为例:

class Foo
{
public:
    virtual void vMethod()
    {
        std::cout << "Foo::vMethod was called!" << std::endl;
    }
};

class Bar : public Foo
{
public:
    virtual void vMethod()
    {
        std::cout << "Bar::vMethod was called!" << std::endl;
        std::cout << "This is not the same as Foo::vMethod." << std::endl;
    }
};

Foo* foo = new Bar;
foo->vMethod();

这将打印 Bar 的消息.在大多数非常规情况下,编译器无法提前知道在其上调用虚拟方法的对象的类型.如上所述,vtable通过提供统一的查找机制来查找方法实现而解决了该问题,无论对象的类型如何.

This will print Bar's message. In most non-trivial scenarios, your compiler cannot know in advance the type of the object on which a virtual method is called. As mentioned above, the vtable solves the problem by providing a uniform lookup mechanism to find method implementations, no matter the type of an object.

一个类的每个实例中都必须存在一个vtable指针(它需要一个额外的内存指针大小,可能是4或8个字节),并且在程序地址空间中的某个位置上的静态内存可以忽略不计.在您看来,这似乎并不多(确实很多人都会同意),但是在某些情况下(例如,内存受极端限制的嵌入式系统),这可能会很麻烦.每个类都有vtable会违反一般的C ++原则,即只为使​​用的东西付费,因此,如果不需要的话,编译器不会生成任何vtable.

A vtable pointer must exist in every instance of a class (which requires the size of a pointer of additional memory, likely to be 4 or 8 bytes), and some insignificant amount of statical memory somewhere in your program's address space. This may not seem a lot to you (and indeed many people would agree), but this can be cumbersome in certain scenarios (like embedded systems where memory is extremely limited). Having vtables for each class would violate the general C++ principle that you pay only for what you use, and therefore the compiler doesn't generate any vtable if it doesn't have to.

没有vtable具有明显的副作用,即禁用 r un t ime t ype i 信息.如果您需要在代码中使用 RTTI ,则您的类必须至少具有一个虚拟方法.在这种情况下,惯例是将析构函数标记为虚拟.

Not having a vtable has the notable side effect of disabling runtime type information. If you need to use RTTI in your code, your classes must have at least one virtual method. The convention is to mark the destructor virtual in these cases.

这篇关于编译器是否为所有类都为其创建了Vtable?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆