multiple virtual table pointers


A

amit

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...
 
Ad

Advertisements

S

Salt_Peter

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.
 
Ad

Advertisements

J

James Kanze

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top