Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   multiple virtual table pointers (http://www.velocityreviews.com/forums/t646392-multiple-virtual-table-pointers.html)

amit 11-28-2008 05:53 AM

multiple virtual table pointers
 
hi all,

I have one doubt regarding virtual table pointers...

Lets say we have 5 base classes each having its own virtual function.
So each of the 5 base class will have a (hidden) virtual table
pointer.
Lets assume each pointer is 4 bytes in size.

Now all these 5 base classes are derived by a derived class.
in main if I create an object of the derived class and print the size
of the object the size will be 20.

ex:
main()
{
derived d1;
cout << sizeof d << "\n";
}


As far as I know the size is 20 because the memory layout for the
derived object will be as below

------------------------------------------------------
| data of base 1 --> vptr pointer |
| data of base 2 --> vptr pointer |
| data of base 3 --> vptr pointer |
| data of base 4 --> vptr pointer |
| data of base 5 --> vptr pointer |
| data of derived --> nothing... |
|------------------------------------------------------

So 20 bytes is understandable.


Question 1:
But now suppose I a virtual function in the derived class. The derived
class would look as below:

class derived
: public base1, public base2, public base3, public base3,
public base4, public base5
{
public :
virtual void d1() { ......}

}

main()
{
derived der;

cout << sizeof der;

}


The above code still prints the value as 20. So it means that the
derived class's virtual function declaration DID NOT result in a vptr
pointer for "derived" class.
If this is true then the entry for the virtual function "d1" should be
added to one of the virtual tables pointed by the base class.

Am I correct?

Question 2:
If yes then does it add the entry for the virtual function "d1" inside
the virtual table pointed by the base1 ?


Question 3:
I have also observed that if a new class save level3 inherits derived
and we create an object of type level3, the size of the level3 object
is also 20.
Probably if i create a virtual function inside level3 class and create
an object of level3 the size might still be 20.
Then if i create one more class called level4 and inherit level3 and
create an object of class level4 the size would still be 20.
So my quesiton is for all these chain of derivations... do the entries
get added to the vtable pointed to be the leftmost derived class of
"derived" ?

(I just hope I did not confuse you guys...)

thanks...

Salt_Peter 11-28-2008 07:13 AM

Re: multiple virtual table pointers
 
On Nov 28, 12:53 am, amit <amitkee...@gmail.com> wrote:
> hi all,
>
> I have one doubt regarding virtual table pointers...
>
> Lets say we have 5 base classes each having its own virtual function.
> So each of the 5 base class will have a (hidden) virtual table
> pointer.
> Lets assume each pointer is 4 bytes in size.
>
> Now all these 5 base classes are derived by a derived class.
> in main if I create an object of the derived class and print the size
> of the object the size will be 20.
>
> ex:
> main()
> {
> derived d1;
> cout << sizeof d << "\n";
>
> }
>
> As far as I know the size is 20 because the memory layout for the
> derived object will be as below
>
> ------------------------------------------------------
> | data of base 1 --> vptr pointer |
> | data of base 2 --> vptr pointer |
> | data of base 3 --> vptr pointer |
> | data of base 4 --> vptr pointer |
> | data of base 5 --> vptr pointer |
> | data of derived --> nothing... |
> |------------------------------------------------------
>
> So 20 bytes is understandable.
>
> Question 1:
> But now suppose I a virtual function in the derived class. The derived
> class would look as below:
>
> class derived
> : public base1, public base2, public base3, public base3,
> public base4, public base5
> {
> public :
> virtual void d1() { ......}
>
> }
>
> main()
> {
> derived der;
>
> cout << sizeof der;
>
> }
>
> The above code still prints the value as 20. So it means that the
> derived class's virtual function declaration DID NOT result in a vptr
> pointer for "derived" class.
> If this is true then the entry for the virtual function "d1" should be
> added to one of the virtual tables pointed by the base class.
>
> Am I correct?
>
> Question 2:
> If yes then does it add the entry for the virtual function "d1" inside
> the virtual table pointed by the base1 ?
>
> Question 3:
> I have also observed that if a new class save level3 inherits derived
> and we create an object of type level3, the size of the level3 object
> is also 20.
> Probably if i create a virtual function inside level3 class and create
> an object of level3 the size might still be 20.
> Then if i create one more class called level4 and inherit level3 and
> create an object of class level4 the size would still be 20.
> So my quesiton is for all these chain of derivations... do the entries
> get added to the vtable pointed to be the leftmost derived class of
> "derived" ?
>
> (I just hope I did not confuse you guys...)
>
> thanks...


The vtable, if that is the mechanism used to provide polymorphism,
doesn't change the sizeof() of a derived object in any way. A derived
object is like a new shell around a base object. So the derived
object's sizeof() is simply a sum of of what is within [base /w
members + derived members].

That vtable is statically created and populated for each base class.
All it does is redirect calls (or overides) to the appropriate
function in the inheritance hierarchy. Polymorphic behaviors don't
modify the sizeof() objects.

Paul is a Person, he weighs 75kg whether he's a Person who talks
German, English or Arabic. His weight doesn't change if he learns a
new language.


James Kanze 11-28-2008 09:32 AM

Re: multiple virtual table pointers
 
On Nov 28, 6:53 am, amit <amitkee...@gmail.com> wrote:
> I have one doubt regarding virtual table pointers...


> Lets say we have 5 base classes each having its own virtual
> function. So each of the 5 base class will have a (hidden)
> virtual table pointer. Lets assume each pointer is 4 bytes in
> size.


> Now all these 5 base classes are derived by a derived class.
> in main if I create an object of the derived class and print
> the size of the object the size will be 20.


> ex:
> main()
> {
> derived d1;
> cout << sizeof d << "\n";
> }


> As far as I know the size is 20 because the memory layout for
> the derived object will be as below


> ------------------------------------------------------
> | data of base 1 --> vptr pointer |
> | data of base 2 --> vptr pointer |
> | data of base 3 --> vptr pointer |
> | data of base 4 --> vptr pointer |
> | data of base 5 --> vptr pointer |
> | data of derived --> nothing... |
> |------------------------------------------------------


> So 20 bytes is understandable.


That corresponds to a frequent implementation, yes.

> Question 1:
> But now suppose I a virtual function in the derived class. The
> derived class would look as below:


> class derived
> : public base1, public base2, public base3, public base3,
> public base4, public base5
> {
> public :
> virtual void d1() { ......}
> }


> main()
> {
> derived der;
> cout << sizeof der;
> }


> The above code still prints the value as 20. So it means that
> the derived class's virtual function declaration DID NOT
> result in a vptr pointer for "derived" class. If this is true
> then the entry for the virtual function "d1" should be added
> to one of the virtual tables pointed by the base class.


> Am I correct?


More or less. It's important to realize that if you have a
base1 object, the vptr it contains will not (necessarily) be the
same as the vtpr in the base1 sub-object of a derived; the
compiler must generate a vtable for base1 in derived, and
initialize the vptr with this in the constructor of derived.
Having done that, it's relatively trivial to simple append
derived's virtual functions to the end of that table.

Note that this is true for all of the base classes; the compiler
could choose any one to which it appended the virtual functions
of derived. Typically, however, it is the first.

> Question 2:
> If yes then does it add the entry for the virtual function
> "d1" inside the virtual table pointed by the base1 ?


It appends it to the end. (It cannot change the structure of
the vtable of base1 if the code is to work.)

> Question 3:
> I have also observed that if a new class save level3 inherits
> derived and we create an object of type level3, the size of
> the level3 object is also 20. Probably if i create a virtual
> function inside level3 class and create an object of level3
> the size might still be 20. Then if i create one more class
> called level4 and inherit level3 and create an object of class
> level4 the size would still be 20. So my quesiton is for all
> these chain of derivations... do the entries get added to the
> vtable pointed to be the leftmost derived class of "derived" ?


That's the usual implementation, in such cases.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


All times are GMT. The time now is 11:05 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.