Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to determine sizeof class with virtual functions?

Tags:

c++

sizeof

vtable

this is kind of homework question. For the following code,

#include <iostream>
using namespace std;

class A
{
public:
    virtual void f(){}
};

class B
{
public:
    virtual void f2(){}
};

class C: public A, public B
{
public: 
    virtual void f3(){}
};

class D: public C
{
public:
    virtual void f4(){}
};

int main()
{
    cout<<sizeof(D)<<endl;
}

The output is: 8

Could anyone please explain how it is 8 bytes? If the vtable implementation is compiler dependent, what should I answer for this kind of question in interviews? What about virtual base classes?

EDIT: i am working on a 32-bit platform.

like image 842
bjskishore123 Avatar asked Jan 22 '11 05:01

bjskishore123


2 Answers

This is of course implementation-dependent. And it would make a terrible interview question. A good C++ programmer can just trust sizeof to be right and let the compiler worry about those vtable things.

But what's going on here is that a typical vtable-based implementation needs two vtables in objects of class C or D. Each base class needs its own vtable. The new virtual methods added by C and D can be handled by extending the vtable format from one base class, but the vtables used by A and B can't be combined.

In pseudo-C-code, here's how a most derived object of type D looks on my implementation (g++ 4.4.5 Linux x86):

void* D_vtable_part1[] = { (void*) 0, &D_typeinfo, &A::f1, &C::f3, &D::f4 };
void* D_vtable_part2[] = { (void*) -4, &D_typeinfo, &B::f2 };

struct D {
  void** vtable_A;
  void** vtable_B;
};

D d = { D_vtable_part1 + 1, D_vtable_part2 + 1 };
like image 174
aschepler Avatar answered Nov 04 '22 07:11

aschepler


In this question if you try to get Sizeof class A, it will give you answer '4' because A have only one virtual function so its __vptr will be of '4' byte.

In the same way, if you try to get Sizeof class B, it will give you answer '4' because B also have only one virtual function so its __vptr will be of '4' byte.

But class C is inheriting both classes A & B and C itself have a virtual function. So C will receive 2 __vptr pointers, and for its own virtual function C will use the inherited __vptr. So if you try to get Sizeof class C, it will give you answer '8' because C have two virtual pointers.

And lastly class D is inheriting class C so D will use inherited __vptr for its own virtual function and because class C have sizeof '8' byte so sizeof D will give you answer '8' byte.

like image 21
iPhoneBuddy Avatar answered Nov 04 '22 08:11

iPhoneBuddy