Why parent classes' vptrs are stored in derived objects

Discussion in 'C++' started by KishorAditya@gmail.com, Feb 27, 2007.

  1. Guest

    Hi All,
    Consider the following scenario:
    class Top { };
    class Left: virtual public Top { };
    class Right: virtual public Top { };
    class Bottom: public Left, public Right {};

    Many books propose that object of Bottom contains three vptrs, one for
    Left and Bottom, one for Right and one for Top.
    Now my question is why the compiler is storing superclasses' vptrs in
    derived class object. After all Bottom also has a vptr pointing to its
    vtable from which it will call all virtual functions.
    Thanks in advance.
    , Feb 27, 2007
    #1
    1. Advertising

  2. Guest

    wrote:
    > Hi All,
    > Consider the following scenario:
    > class Top { };
    > class Left: virtual public Top { };
    > class Right: virtual public Top { };
    > class Bottom: public Left, public Right {};
    >
    > Many books propose that object of Bottom contains three vptrs, one for
    > Left and Bottom, one for Right and one for Top.
    > Now my question is why the compiler is storing superclasses' vptrs in
    > derived class object. After all Bottom also has a vptr pointing to its
    > vtable from which it will call all virtual functions.
    > Thanks in advance.


    Well as far as you use derived object alone it works fine. But what
    happens when you dynamic cast Bottom pointer to either of Left, Right
    or Top like:
    Bottom * b = new Bottom;
    Left * something = <dynamic_cast*>b;
    In this case you type casting you should use something as if it is a
    original Left object; for that you need to access Left class' vtbl.
    Thats why you need to store base classes vptrs in the derived objects.
    Hope its clear.
    , Feb 27, 2007
    #2
    1. Advertising

  3. Ron House Guest

    wrote:
    > wrote:
    >
    >>Hi All,
    >>Consider the following scenario:
    >>class Top { };
    >>class Left: virtual public Top { };
    >>class Right: virtual public Top { };
    >>class Bottom: public Left, public Right {};
    >>
    >>Many books propose that object of Bottom contains three vptrs, one for
    >>Left and Bottom, one for Right and one for Top.
    >>Now my question is why the compiler is storing superclasses' vptrs in
    >>derived class object. After all Bottom also has a vptr pointing to its
    >>vtable from which it will call all virtual functions.
    >>Thanks in advance.

    >
    >
    > Well as far as you use derived object alone it works fine. But what
    > happens when you dynamic cast Bottom pointer to either of Left, Right
    > or Top like:
    > Bottom * b = new Bottom;
    > Left * something = <dynamic_cast*>b;
    > In this case you type casting you should use something as if it is a
    > original Left object; for that you need to access Left class' vtbl.
    > Thats why you need to store base classes vptrs in the derived objects.
    > Hope its clear.
    >


    No that's not clear. When calling a method from a Left*, if it points to
    a Bottom, then Bottom's virtual functions should be used, not Left's.

    --
    Ron House
    http://www.sci.usq.edu.au/staff/house
    Ron House, Mar 1, 2007
    #3
  4. Guest

    Yes, you are right Ron. Bit misunderstood the question.
    May be this explanation is clear:

    class D : public A, public B, public C {.........}

    If we dont store the base classes' vptrs in derived objects, that
    means you have to club all the virtual functions of all the base
    classes (in case of multiple inheritance) into one vtbl that has a
    single vptr that will be stored in your object. Now, no problem in
    accessing virtual functions of first subobject (like class A in the
    above code snippet) whose virtual function pointers are stored in
    starting location of vtbl. But what happens in accessing other
    subobjects (like classes B and C in the above code snippet) virtual
    functions. Their offsets will get disturbed as you have clubbed all
    the virtual functions into one vtbl. After all, compiler will access
    virtual functions with their offsets only. Now you dont know what will
    be get called.

    Thats why in case of single or pure multilevel inheritance you dont hv
    to store the base classes' vptrs in derived objects.

    Now the question: Can not compiler determine these changes in offsets
    and adjust virtual functions pointers accordingly? It may, it depends
    on the compiler. But most of the compilers adopt this strategy and may
    some compilers do this optimization.
    , Mar 1, 2007
    #4
  5. Ron House Guest

    wrote:
    > Yes, you are right Ron. Bit misunderstood the question.
    > May be this explanation is clear:
    >
    > class D : public A, public B, public C {.........}
    >
    > If we dont store the base classes' vptrs in derived objects, that
    > means you have to club all the virtual functions of all the base
    > classes (in case of multiple inheritance) into one vtbl that has a
    > single vptr that will be stored in your object. Now, no problem in
    > accessing virtual functions of first subobject (like class A in the
    > above code snippet) whose virtual function pointers are stored in
    > starting location of vtbl. But what happens in accessing other
    > subobjects (like classes B and C in the above code snippet) virtual
    > functions. Their offsets will get disturbed as you have clubbed all
    > the virtual functions into one vtbl. After all, compiler will access
    > virtual functions with their offsets only. Now you dont know what will
    > be get called.
    >
    > Thats why in case of single or pure multilevel inheritance you dont hv
    > to store the base classes' vptrs in derived objects.
    >
    > Now the question: Can not compiler determine these changes in offsets
    > and adjust virtual functions pointers accordingly? It may, it depends
    > on the compiler. But most of the compilers adopt this strategy and may
    > some compilers do this optimization.
    >


    Yes, with multiple inheritance, obviously A, B, and C cannot all share
    the same starting address as D, so yes, there must be an offset on the
    address of the _data_ of the object, when calling superclass functions
    (of all but 1); and there must be distinct vtable addresses for all but
    1 also. But like you, I cannot think why this cannot be calculated. My
    only suggestion is that perhaps it is a performance issue. But even
    here, surely all such objects will have the same relationships, so the
    extra addresses could be stored in the vtable, I would have thought.

    We must be overlooking something (unless the book authors are)!

    --
    Ron House
    http://www.sci.usq.edu.au/staff/house
    Ron House, Mar 2, 2007
    #5
    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. Doug
    Replies:
    7
    Views:
    363
    xarax
    May 13, 2004
  2. Colin Goudie
    Replies:
    6
    Views:
    450
    Victor Bazarov
    Jan 26, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,671
    Smokey Grindel
    Dec 2, 2006
  4. Replies:
    1
    Views:
    378
    myork
    May 23, 2007
  5. Replies:
    1
    Views:
    369
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page