multiple virtual table pointers

Discussion in 'C++' started by amit, Nov 28, 2008.

  1. amit

    amit Guest

    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...
     
    amit, Nov 28, 2008
    #1
    1. Advertising

  2. amit

    Salt_Peter Guest

    On Nov 28, 12:53 am, amit <> 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.
     
    Salt_Peter, Nov 28, 2008
    #2
    1. Advertising

  3. amit

    James Kanze Guest

    On Nov 28, 6:53 am, amit <> 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:
    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
     
    James Kanze, Nov 28, 2008
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Williams
    Replies:
    2
    Views:
    1,140
    Jacob Yang [MSFT]
    Aug 12, 2003
  2. Rio
    Replies:
    4
    Views:
    1,204
  3. Josh Lessard
    Replies:
    11
    Views:
    676
    Andrey Tarasevich
    Nov 6, 2003
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    688
  5. PT
    Replies:
    1
    Views:
    401
    Ken Schaefer
    Oct 7, 2004
Loading...

Share This Page