Vtable与继承和虚拟继承的区别

时间:2015-11-20 07:54:10

标签: c++ vtable virtual-inheritance

我试图在C ++中学习V-table的实现。我使用g ++的 -fdump-class-hierarchy 选项来了解虚拟表的外观。要理解' 偏移到顶部' RTTI ',虚拟功能 v-table 中的>等。然后,我通过虚拟推导我的类来尝试相同的操作,并且可以看到添加了许多条目。

代码:

class Base
{
   public:
      virtual void print() { cout << "Base Print" << endl; }
};

class Derived1 : public Base
{
   public:
      virtual void print() { cout << "Derived1 Print" << endl; }
};

这给出了以下vtable:

Vtable for Base
Base::_ZTV4Base: 3u entries
0     0u
4     (int (*)(...))(&_ZTI4Base)
8     Base::print

Class Base
   size=4 align=4
   base size=4 base align=4
Base (0xb6f51480) 0 nearly-empty
    vptr=((&Base::_ZTV4Base) + 8u)

Vtable for Derived1
Derived1::_ZTV8Derived1: 3u entries
0     0u
4     (int (*)(...))(&_ZTI8Derived1)
8     Derived1::print

Class Derived1
   size=4 align=4
   base size=4 base align=4
Derived1 (0xb6f51980) 0 nearly-empty
    vptr=((&Derived1::_ZTV8Derived1) + 8u)
  Base (0xb6f519c0) 0 nearly-empty
      primary-for Derived1 (0xb6f51980)

现在,如果我使用

派生虚拟
class Derived1 : public virtual Base

我得到以下

Vtable for Base
Base::_ZTV4Base: 3u entries
0     0u                           <----- Offset to top pointer
4     (int (*)(...))(&_ZTI4Base)   <----- RTTI Pointer
8     Base::print                  <----- Virtual Function

Class Base
   size=4 align=4
   base size=4 base align=4
Base (0xb6f51480) 0 nearly-empty
    vptr=((&Base::_ZTV4Base) + 8u)  <----- This takes to Base::print ?

Vtable for Derived1
Derived1::_ZTV8Derived1: 5u entries
0     0u   <---- Which of these 2 is virtual base offset and what is other one?
4     0u    
8     0u    <---- offset to top for Derived1
12    (int (*)(...))(&_ZTI8Derived1)  <----- RTTI Pointer
16    Derived1::print                 <----- Virtual Function

VTT for Derived1
Derived1::_ZTT8Derived1: 2u entries
0     (const void*)((void*)((&Derived1::_ZTV8Derived1) + 16u)) <--- Why 2 same entries here ?
4     (const void*)((void*)((&Derived1::_ZTV8Derived1) + 16u))

Class Derived1
   size=4 align=4
   base size=4 base align=4
Derived1 (0xb6f51980) 0 nearly-empty
    vptridx=0u vptr=((&Derived1::_ZTV8Derived1) + 16u) <----- This takes to Derived1::print ?
  Base (0xb6f519c0) 0 nearly-empty virtual
      primary-for Derived1 (0xb6f51980)
      vptridx=4u vbaseoffset=-0x000000010

问题:

  • 为什么有补偿(0u)的额外条目?
  • &#34; VTT &#34;的目的是什么?部分它包含什么?
  • 什么是 vptridx

我在SO和外面经历了各种链接,但无法得到完整的解释。

感谢您提前回复。

修改: 非常感谢链接(重复)。我在上面的评论中加入了我的理解。但是还有一些问题吗?有人可以帮忙吗?

0 个答案:

没有答案