Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does virtual keyword increase the size of derived a class?

I have two classes - one base class and one derived from it :

class base {

 int i ;

  public :
  virtual ~ base () { }
};

class derived :  virtual public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

Here the answer is 16. But if I do instead a non-virtual public inheritance or make the base class non-polymorphic , then I get the answer as 12, i.e. if I do :

class base {

 int i ;

 public :
virtual ~ base () { }
};

class derived :  public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

OR

class base {

int i ;

public :
~ base () { }
};

class derived :  virtual public base { int j ; };

main()

{ cout << sizeof ( derived ) ; }

In both the cases answer is 12.

Can someone please explain why there is a difference in the size of the derived class in 1st and the other 2 cases ?

( I work on code::blocks 10.05, if someone really need this )

like image 203
cirronimbo Avatar asked Dec 16 '22 23:12

cirronimbo


1 Answers

There are two separate things here that cause extra overhead.

Firstly, having virtual functions in the base class increases its size by a pointer size (4 bytes in this case), because it needs to store the pointer to the virtual method table:

normal inheritance with virtual functions:

0        4       8       12
|      base      |
| vfptr  |  i    |   j   |

Secondly, in virtual inheritance extra information is needed in derived to be able to locate base. In normal inheritance the offset between derived and base is a compile time constant (0 for single inheritance). In virtual inheritance the offset can depend on the runtime type and actual type hierarchy of the object. Implementations may vary, but for example Visual C++ does it something like this:

virtual inheritance with virtual functions:

0        4         8        12        16
                   |      base        |
|  xxx   |   j     |  vfptr |    i    |

Where xxx is a pointer to some type information record, that allows to determine the offset to base.

And of course it's possible to have virtual inheritance without virtual functions:

virtual inheritance without virtual functions:

0        4         8        12
                   |  base  |
|  xxx   |   j     |   i    |
like image 94
Timo Avatar answered Mar 07 '23 22:03

Timo