虚拟功能表 [英] Virtual Function Table

查看:77
本文介绍了虚拟功能表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在派生类中,我不覆盖基类中定义的虚函数.如果我创建基类和派生类的对象,那么将创建多少个虚拟表?

If in derived class I do not override a virtual function defined in base class. Then how many virtual table will be created if I create object of the base and derived classes?

base
{
   virtual xyz()
   {
   }
};

derived: public base
{

};

main()
{
   base bobj;
   derived dobj;

}





Here will the virtual table for derived class be created?

推荐答案

两个.但是在这种情况下,派生类的虚拟表将包含base :: xyz函数指针.
Two.But in this case The virtual table of derived class will contain the base::xyz function pointer.


我怀疑在这种情况下,编译器将足够聪明,可以检测到实际上是否需要 * VFT:

1. base从不 *需要一个,因为它将始终使用其自己的方法. *
2. derived类不会覆盖任何虚函数,因此也不需要VFT. *(请参见下文)

如果在derived中添加了替代,则仅必须添加类derived的VFT. 此外,此类创建的任何实例都将需要额外的内存来存储指向VFT的指针(然后再次声明,如果您使用运行时类型信息或托管C ++中的程序,则可能已经存在指向与类相关的指针信息,因此您可能不会注意到内存消耗方面的差异)

* P.S. -更正:
derived 必须具有虚拟功能表!原因是,如果在另一个编译单元甚至另一个库中,类derived2是从derived派生的,并且实际上覆盖了xyz(),那么任何通过derived*类型的指针访问对象的代码都必须在运行时确定此对象真正是什么类,以及是否必须调用base中的版本或其他版本.

因此,Emilio发布的内容是正确的.我什至没有意识到共享vtable的可能性,但这很有意义.
I suspect in this case the compiler will be clever enough to detect that no* VFT is actually required:

1. the base class never* needs one as it will always use it''s own methods.*
2. The derived class doesn''t override any virtual function, so doesn''t need a VFT either.*(see below)

If you added an override in derived, only then a VFT for class derived would have to be added. Also, any instance created of this class will require additional memory for a pointer to the VFT (then again, if you use run-time type information or program in managed C++, there may already be a pointer to class-related information, so you may not notice a difference in memory consumption)

*P.S. - a correction:
The class derived must have a virtual function table! The reason is that if in another compilation unit, or even another library, a class derived2 is derived from derived and overrides xyz() virtually, then any code accessing an object through a pointer of type derived* will have to decide at runtime what class this object really is, and whether the version in base, or another has to be called.

So, what Emilio posted is correct. I wasn''t even aware of the possibility of sharing a vtable, but it makes sense.


C ++编译器实现动态方法分派的方式取决于...实现,并且可以甚至不基于v表的概念.

C ++规范说的是:
*所有方法都是继承的
*每种方法都可以覆盖
*虚拟方法的替代是virtual
*对虚拟方法的隐式或-间接调用始终导致对调用的派生程度最高.

对于C ++程序员而言,编译器如何做到这一点不是问题,但对于编译器开发人员而言,是一个问题.

V表的使用只是一种非常普遍的技术.如果采用这种方式,则在您的情况下,由于您的derived 具有虚拟方法(它是从base继承的),它必须具有vtable指针(就像base一样). >
请注意,这些对象没有vtable,而只有指向vtable的指针,该指针在相同类型的所有对象之间共享.

但是,由于您derived 没有为base添加任何内容,因此编译器可以优化使两者共享同一个vtable,并且由于没有为xyz定义替代,因此进一步的编译器优化可能是使该函数完全不虚拟.

无论如何,您都不在乎.无论是否需要vtable,编译器都会生成它,并且所有类实例都将具有vtable指针.
The way a C++ compiler implements the dynamic method dispatching is ... implementation dependent, and can even be not base on the concept of v-tables.

What the C++ specs says is that:
* all methods are inherited
* every method can be overridden
* the override of a virtual method is virtual
* an implicit or -indirect call to a virtual method always result in a call the most derived override.

How the compiler does this is not a problem for a C++ programmer, but for the compiler developer.

The use of V-tables is just a very common technique. If this is adopted, in your case, since your derived has a virtual method (it inherits that from base) it must have a vtable pointer (just like base has).

Note that the objects don''t have vtables, but just a pointers that point to a vtable that is shared among all the object of the same type.

But since you derived adds nothing to base, a compiler can optimize making both sharing a same vtable, and since no overrides are defined for xyz, a further compiler optimization may be to make that function non virtual at all.

In any case you shouldn''t care. Whether a vtable is required, the compiler will generate it and all the class instances will have a vtable pointer.


这篇关于虚拟功能表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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