Vtable, vptr content and size postmortem

#include<iostream>
using namespace std;
class EmptyClass
{};
class PolymorphicVF
{
virtual void vf(){}
};
class PolymorphicDesstructor
{
virtual ~PolymorphicDesstructor()
{
}
};
class PolymorphicPureDestructor
{
virtual ~PolymorphicPureDestructor()=0;
};
class AbstractClassWithOnePureVF
{
virtual void pvf()=0;
};

class classWithOnepureVFAnd4vf
{
virtual void vf1(){};
virtual void vf2(){};
virtual void pvf()=0;
virtual void vf3(){};
virtual void vf4(){};
};

class Base
{
public:
virtual void vf(){}
};
class SingleDerivedNoOverridevf: public Base
{
};
class SingleDerivedNoOverridevf1: public Base
{
};
class SingleDerivedNoOverridevf2AndOneDM: public Base
{
public:
    char c;
};
class SingleDerivedWithOverridevf: virtual public Base
{
public:
    void vf(){}
};
class SingleDerivedWithOverridevf1: virtual public Base
{
public:
    void vf(){}
};;
class DiamiondProblemWithNoFinalOverrider:public SingleDerivedNoOverridevf, public SingleDerivedNoOverridevf1
{
};
class DiamiondProblemWithFinalOverrider:public SingleDerivedWithOverridevf, public SingleDerivedWithOverridevf1
{
void vf(){}
};
class DiamondDerivedWithThree:public SingleDerivedWithOverridevf, public SingleDerivedWithOverridevf1, public SingleDerivedNoOverridevf1
{
void vf(){}
};
class DerivedWithThreeDifferent:public EmptyClass,public PolymorphicVF,public PolymorphicDesstructor
{};
int main()
{
cout<<"sizeof(EmptyClass)="<<sizeof(EmptyClass)<<endl;//1
cout<<"sizeof(PolymorphicVF)="<<sizeof(PolymorphicVF)<<endl;//8
cout<<"sizeof(PolymorphicDesstructor)="<<sizeof(PolymorphicDesstructor)<<endl;//8
cout<<"sizeof(PolymorphicPureDestructor)="<<sizeof(PolymorphicPureDestructor)<<endl;//8
cout<<"sizeof(AbstractClassWithOnePureVF)="<<sizeof(AbstractClassWithOnePureVF)<<endl;//8
cout<<"sizeof(classWithOnepureVFAnd4vf)="<<sizeof(classWithOnepureVFAnd4vf)<<endl;//8
cout<<"sizeof(Base with one vf)="<<sizeof(Base)<<endl;//8
cout<<"sizeof(SingleDerivedNoOverridevf)="<<sizeof(SingleDerivedNoOverridevf)<<endl;//8
cout<<"sizeof(SingleDerivedNoOverridevf2AndOneDM)="<<sizeof(SingleDerivedNoOverridevf2AndOneDM)<<endl;//16
cout<<"sizeof(SingleDerivedWithOverridevf)="<<sizeof(SingleDerivedWithOverridevf)<<endl;//8
cout<<"sizeof(DiamiondProblemWithNoFinalOverrider)="<<sizeof(DiamiondProblemWithNoFinalOverrider)<<endl;//16
cout<<"sizeof(DiamiondProblemWithFinalOverrider)="<<sizeof(DiamiondProblemWithFinalOverrider)<<endl;//16
cout<<"sizeof(DiamondDerivedWithThree)="<<sizeof(DiamondDerivedWithThree)<<endl;//24
cout<<"sizeof(DerivedWithThreeDifferent)="<<sizeof(DerivedWithThreeDifferent)<<endl;//24

return 0;
}
/*
sizeof(EmptyClass)=1
sizeof(PolymorphicVF)=8
sizeof(PolymorphicDesstructor)=8
sizeof(PolymorphicPureDestructor)=8
sizeof(AbstractClassWithOnePureVF)=8
sizeof(classWithOnepureVFAnd4vf)=8
sizeof(Base with one vf)=8
sizeof(SingleDerivedNoOverridevf)=8
sizeof(SingleDerivedNoOverridevf2AndOneDM)=16
sizeof(SingleDerivedWithOverridevf)=8
sizeof(DiamiondProblemWithNoFinalOverrider)=16
sizeof(DiamiondProblemWithFinalOverrider)=16
sizeof(DiamondDerivedWithThree)=24
sizeof(DerivedWithThreeDifferent)=16
*/

//How to check content of vtable
//compiled with command:
//g++ -fdump-class-hierarchy vtable.cpp

//vtables are taken from generated class table file by above command:
//vtable.cpp.002t.class

Class EmptyClass
   size=1 align=1
   base size=0 base align=1
EmptyClass (0x0x7fc113139d80) 0 empty
//No vtable for non polymorphic class EmptyClass

Vtable for PolymorphicVF
PolymorphicVF::_ZTV13PolymorphicVF: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI13PolymorphicVF)
16    (int (*)(...))PolymorphicVF::vf

Class PolymorphicVF
   size=8 align=8
   base size=8 base align=8
PolymorphicVF (0x0x7fc113139de0) 0 nearly-empty
    vptr=((& PolymorphicVF::_ZTV13PolymorphicVF) + 16u)


Vtable for PolymorphicDesstructor
PolymorphicDesstructor::_ZTV22PolymorphicDesstructor: 4u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI22PolymorphicDesstructor)
16    (int (*)(...))PolymorphicDesstructor::~PolymorphicDesstructor
24    (int (*)(...))PolymorphicDesstructor::~PolymorphicDesstructor

Vtable for PolymorphicPureDestructor
PolymorphicPureDestructor::_ZTV25PolymorphicPureDestructor: 4u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI25PolymorphicPureDestructor)
16    (int (*)(...))__cxa_pure_virtual
24    (int (*)(...))__cxa_pure_virtual

Vtable for AbstractClassWithOnePureVF
AbstractClassWithOnePureVF::_ZTV26AbstractClassWithOnePureVF: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI26AbstractClassWithOnePureVF)
16    (int (*)(...))__cxa_pure_virtual

Vtable for classWithOnepureVFAnd4vf
classWithOnepureVFAnd4vf::_ZTV24classWithOnepureVFAnd4vf: 7u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI24classWithOnepureVFAnd4vf)
16    (int (*)(...))classWithOnepureVFAnd4vf::vf1
24    (int (*)(...))classWithOnepureVFAnd4vf::vf2
32    (int (*)(...))__cxa_pure_virtual
40    (int (*)(...))classWithOnepureVFAnd4vf::vf3
48    (int (*)(...))classWithOnepureVFAnd4vf::vf4

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

Vtable for SingleDerivedNoOverridevf
SingleDerivedNoOverridevf::_ZTV25SingleDerivedNoOverridevf: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI25SingleDerivedNoOverridevf)
16    (int (*)(...))Base::vf

Vtable for SingleDerivedNoOverridevf1
SingleDerivedNoOverridevf1::_ZTV26SingleDerivedNoOverridevf1: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI26SingleDerivedNoOverridevf1)
16    (int (*)(...))Base::vf

Vtable for SingleDerivedNoOverridevf2AndOneDM
SingleDerivedNoOverridevf2AndOneDM::_ZTV34SingleDerivedNoOverridevf2AndOneDM: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI34SingleDerivedNoOverridevf2AndOneDM)
16    (int (*)(...))Base::vf

Vtable for SingleDerivedWithOverridevf
SingleDerivedWithOverridevf::_ZTV27SingleDerivedWithOverridevf: 5u entries
0     0u
8     0u
16    (int (*)(...))0
24    (int (*)(...))(& _ZTI27SingleDerivedWithOverridevf)
32    (int (*)(...))SingleDerivedWithOverridevf::vf


Vtable for SingleDerivedWithOverridevf1
SingleDerivedWithOverridevf1::_ZTV28SingleDerivedWithOverridevf1: 5u entries
0     0u
8     0u
16    (int (*)(...))0
24    (int (*)(...))(& _ZTI28SingleDerivedWithOverridevf1)
32    (int (*)(...))SingleDerivedWithOverridevf1::vf


Vtable for DiamiondProblemWithNoFinalOverrider
DiamiondProblemWithNoFinalOverrider::_ZTV35DiamiondProblemWithNoFinalOverrider: 6u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI35DiamiondProblemWithNoFinalOverrider)
16    (int (*)(...))Base::vf
24    (int (*)(...))-8
32    (int (*)(...))(& _ZTI35DiamiondProblemWithNoFinalOverrider)
40    (int (*)(...))Base::vf


Vtable for DiamiondProblemWithFinalOverrider
DiamiondProblemWithFinalOverrider::_ZTV33DiamiondProblemWithFinalOverrider: 10u entries
0     0u
8     0u
16    (int (*)(...))0
24    (int (*)(...))(& _ZTI33DiamiondProblemWithFinalOverrider)
32    (int (*)(...))DiamiondProblemWithFinalOverrider::vf
40    18446744073709551608u
48    18446744073709551608u
56    (int (*)(...))-8
64    (int (*)(...))(& _ZTI33DiamiondProblemWithFinalOverrider)
72    (int (*)(...))DiamiondProblemWithFinalOverrider::_ZThn8_N33DiamiondProblemWithFinalOverrider2vfEv

Vtable for DiamondDerivedWithThree
DiamondDerivedWithThree::_ZTV23DiamondDerivedWithThree: 13u entries
0     0u
8     0u
16    (int (*)(...))0
24    (int (*)(...))(& _ZTI23DiamondDerivedWithThree)
32    (int (*)(...))DiamondDerivedWithThree::vf
40    18446744073709551608u
48    18446744073709551608u
56    (int (*)(...))-8
64    (int (*)(...))(& _ZTI23DiamondDerivedWithThree)
72    (int (*)(...))DiamondDerivedWithThree::_ZThn8_N23DiamondDerivedWithThree2vfEv
80    (int (*)(...))-16
88    (int (*)(...))(& _ZTI23DiamondDerivedWithThree)
96    (int (*)(...))DiamondDerivedWithThree::_ZThn16_N23DiamondDerivedWithThree2vfEv



Vtable for DerivedWithThreeDifferent
DerivedWithThreeDifferent::_ZTV25DerivedWithThreeDifferent: 9u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI25DerivedWithThreeDifferent)
16    (int (*)(...))PolymorphicVF::vf
24    (int (*)(...))DerivedWithThreeDifferent::~DerivedWithThreeDifferent
32    (int (*)(...))DerivedWithThreeDifferent::~DerivedWithThreeDifferent
40    (int (*)(...))-8
48    (int (*)(...))(& _ZTI25DerivedWithThreeDifferent)
56    (int (*)(...))DerivedWithThreeDifferent::_ZThn8_N25DerivedWithThreeDifferentD1Ev
64    (int (*)(...))DerivedWithThreeDifferent::_ZThn8_N25DerivedWithThreeDifferentD0Ev

1 comment:

  1. //vtable in muilple inheritance
    #include
    using namespace std;

    class base
    {
    public:
    virtual void vf1(){}
    virtual void vf2(){}
    };
    class derived1: virtual public base
    {
    void vf1(){}
    void vf2(){}
    virtual void vf11(){}

    };
    class derived2: virtual public base
    {
    void vf1(){}
    void vf2(){}
    virtual void vf21(){}

    };
    class derived3: public derived1, public derived2
    {
    public:
    void vf1(){cout<<"d3::f1"<<endl;}
    void vf2(){cout<<"d3::f2"<<endl;}
    virtual void vf3(){cout<<"d3::f3"<<endl;}
    };

    int main()
    {
    cout<<"sizof base="<<sizeof(base)<<endl;//8
    cout<<"sizof derived1="<<sizeof(derived1)<<endl;//8
    cout<<"sizof derived2="<<sizeof(derived2)<<endl;//8
    cout<<"sizof derived3="<<sizeof(derived3)<<endl;//16
    derived3 d3;
    d3.vf1();//d3::f1

    return 0;
    }
    /*
    Vtable for derived3
    derived3::_ZTV8derived3: 17u entries
    0 0u
    8 0u
    16 0u
    24 (int (*)(...))0
    32 (int (*)(...))(& _ZTI8derived3)
    40 (int (*)(...))derived3::vf1
    48 (int (*)(...))derived3::vf2
    56 (int (*)(...))derived1::vf11
    64 (int (*)(...))derived3::vf3
    72 18446744073709551608u
    80 18446744073709551608u
    88 18446744073709551608u
    96 (int (*)(...))-8
    104 (int (*)(...))(& _ZTI8derived3)
    112 (int (*)(...))derived3::_ZThn8_N8derived33vf1Ev
    120 (int (*)(...))derived3::_ZThn8_N8derived33vf2Ev
    128 (int (*)(...))derived2::vf21
    */
    //implementation Dependant

    ReplyDelete