Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of polymorphic class derived virtually

I am having hard time to undertsand what constitutes the size of following classes?
I am using MSVS 2008 (VC 9.0 compiler). I have read that if I do not declare virtual functions(in below example) then Class D will contain 2 extra pointer(1 from B and another from C) which will point to the shared instance of A.

But what would be the memory map of each classes in below case(having virtual functions also) ?

class A
{
public:
    int a;
    virtual void Func();
public:
    A(void);
    ~A(void);
};

class B :virtual public A
{
public:
    int b;
    virtual void Func();
public:
    B(void);
    ~B(void);
};

class C: virtual public A
{
public:
    int c;
    virtual void Func();
public:
    C(void);
    ~C(void);
};

class D : public B, public C
{
public:
    int d;
    virtual void Func();
public:
    D(void);
    ~D(void);
};




int _tmain(int argc, _TCHAR* argv[])
{
    cout << "size of Class A :" << sizeof(A) << endl;

    cout << "size of Class B :" << sizeof(B) << endl;

    cout << "size of Class C :" << sizeof(C) << endl;

    cout << "size of Class D :" << sizeof(D) << endl;

    return 0;
}

Output:
size of Class A :8
size of Class B :20
size of Class C :20
size of Class D :32

Here, how the size of B, C & D are getting calculated ?

EDIT: Following is the memory map generated by /d1reportSingleClassLayoutXXX compiler option for each class:

1>class A size(8):  
1> +---  
1> 0 | {vfptr}  
1> 4 | a  

1>class B size(20):  //Similar for C
1> +---  
1> 0 | {vbptr}  
1> 4 | b  
1> +---  
1>8 | (vtordisp for vbase A)  
1> +--- (virtual base A)  
1>12 | {vfptr}  
1>16 | a  
1> +---  

1>class D size(32):  
1> +---  
1> | +--- (base class B)  
1> 0 | | {vbptr}  
1> 4 | | b  
1> | +---  
1> | +--- (base class C)  
1> 8 | | {vbptr}  
1>12 | | c  
1> | +---  
1>16 | d  
1> +---  
1>20 | (vtordisp for vbase A)  
1> +--- (virtual base A)  
1>24 | {vfptr}  
1>28 | a    

What is vtordisp for vbase X means here ?

like image 943
SuperNov Avatar asked Feb 28 '14 09:02

SuperNov


People also ask

What is the size of class with virtual function?

A virtual function is a pointer with 8 bytes.

What is the size of derived class?

If compiled with the Microsoft C++ compiler, the size of DerivedClass is 16 bytes. If compiled with gcc (either c++ or g++), size of DerivedClass is 12 bytes.

What is the size of VPTR?

If an empty class contain virtual function, even though there is no data members in the class, its size will not be 1 byte but 4 byte because of virtual pointer i.e. VPTR. Virtual pointer size on 32 bit platform is 4 bytes and on 64 bit it is 8 bytes.

Can a derived class be virtual?

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.


2 Answers

I would say that you are on a 32-bit machine, where sizeof(int) is 4.

Speculatively:

First, the size of A:

|int a (4)|vtable pointer A (4)|

Second, the size of B and C:

|A base instance (8)|pointer to A(4)|int b/c(4)|vtable pointer B/C|

Third, the size of D:

|A base instance (8)|pointer to A(4)|int c(4)|vtable pointer B(4)|pointer to A(4)|int d(4)|vtable pointer C(4)|

Since D is not virtually inheriting from C, it can afford to reuse vtable pointer C. Again, that's just speculation. You should try to dump the memory of an object D to be sure. And I'm not sure how your machine aligns memory.

like image 125
Laurent LA RIZZA Avatar answered Oct 18 '22 14:10

Laurent LA RIZZA


As per Jonathan Caves, MSFT

It is used very rarely - but we have to add it to classes that inherit from a virtual base class and override virtual functions just in case the user does call a virtual function in the constructor or destructor.

So -- it's MSVC's (terribly underdocumented) solution to "how do you make a virtual call during object construction?".

like image 1
LThode Avatar answered Oct 18 '22 15:10

LThode