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 ?
A virtual function is a pointer with 8 bytes.
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.
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.
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.
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.
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?".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With