Virtual method implementation in C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kapil Khosla

    #1

    Virtual method implementation in C++

    Dear all,
    I am trying to underlying implementation of virtual functions in C++.
    The way I understand polymorphism is

    class Base
    {
    public:
    virtual int func();
    };

    class Derived: public Base
    {
    public:
    virtual int func();
    }

    int Base::func()
    {
    printf("In Base\n");
    }

    int Derived::func()
    {
    printf("In Derived\n");
    }

    void poly_func(Base * x)
    {
    x->func();
    }
    int main()
    {
    Derived ob1;
    poly_func(&ob1) ;
    }

    Output :

    This will call the function in the derived class instead of the base
    class due to the virtual keyword in the base class with func().




    Now my question is how does C++ implement such mechanism.
    I read something about VTables in C++, that every class has a
    different VTable which contain the appropriate function to be called.
    So by pushing the pointer to the appropriate VTable you can figure out
    the function to be called.


    They said that at "run time" you would find out which object is really
    being called and thus we need VTables. I dont understand this point.
    In this case it is pretty obvious that &ob1 is being passed so
    compiler can figure out at compile time which real function is to be
    called based on the fact that the virtual keyword is there in the base
    class. Can you give me an example where the compiler would not be able
    to figure out the type of the object being passed at compile time and
    thus show me the need of VTables.

    I am not very familiar with OOPS concept so might not be aware of some
    basic concepts.

    Thanks a lot,
    Kapil
  • John Harrison

    #2
    Re: Virtual method implementation in C++


    "Kapil Khosla" <khoslakapil@ya hoo.com> wrote in message
    news:919aa2da.0 306262147.5eba0 d2d@posting.goo gle.com...[color=blue]
    > Dear all,
    > I am trying to underlying implementation of virtual functions in C++.
    > The way I understand polymorphism is
    >
    > class Base
    > {
    > public:
    > virtual int func();
    > };
    >
    > class Derived: public Base
    > {
    > public:
    > virtual int func();
    > }
    >
    > int Base::func()
    > {
    > printf("In Base\n");
    > }
    >
    > int Derived::func()
    > {
    > printf("In Derived\n");
    > }
    >
    > void poly_func(Base * x)
    > {
    > x->func();
    > }
    > int main()
    > {
    > Derived ob1;
    > poly_func(&ob1) ;
    > }
    >
    > Output :
    >
    > This will call the function in the derived class instead of the base
    > class due to the virtual keyword in the base class with func().
    >
    >
    >
    >
    > Now my question is how does C++ implement such mechanism.
    > I read something about VTables in C++, that every class has a
    > different VTable which contain the appropriate function to be called.
    > So by pushing the pointer to the appropriate VTable you can figure out
    > the function to be called.
    >
    >
    > They said that at "run time" you would find out which object is really
    > being called and thus we need VTables. I dont understand this point.
    > In this case it is pretty obvious that &ob1 is being passed so
    > compiler can figure out at compile time which real function is to be
    > called based on the fact that the virtual keyword is there in the base
    > class. Can you give me an example where the compiler would not be able
    > to figure out the type of the object being passed at compile time and
    > thus show me the need of VTables.
    >
    > I am not very familiar with OOPS concept so might not be aware of some
    > basic concepts.
    >
    > Thanks a lot,
    > Kapil[/color]

    Simple, suppose main and poly_func were in two different files. Then when
    the compiler compiled poly_func it wouldn't know anything about main, so it
    wouldn't know that poly_func was being called with a pointer to Derived.

    Or, what if you changed your code to this

    int main()
    {
    Base obj1;
    Derived obj2;
    poly_func(&obj1 );
    poly_func(&obj2 );
    }

    Now your poly_func function has to deal with both types of object. So the
    same code has to decide whether to call Base::func or Derived::func, so the
    decision must be made at run time.

    john


    Comment

    • Min

      #3
      Re: Virtual method implementation in C++

      First, there is not such thing as class, every thing is a subroutine at
      assembly level. So each method in class becomes a list of
      functions/subroutine. From the compiler point of view, it will remember as
      follow for each method: this function IS this method in that CLASS at
      COMPILE time. But as you demonstrated, you can have a method belonging to
      two classes due to inheritance. So basically, some genius came up with
      VTABLE to find out what the proper one at RUN TIME.


      What exactly is a VTABLE ?
      VTABLE is constructed by the compiler at COMPILE-TIME because it knows about
      each method definition and declaration. Each VTABLE is included in the exe
      file. Think of a VTABLE as a list of function pointers. It has an index
      and value; In your examples, we will have a VTABLE for Base and another
      VTABLE for Derived.


      VTABLE for Base
      --------------
      0 | 0xd3290dl |
      |-------------|
      1 | etc |
      |-------------|

      VTABLE for Derived
      --------------
      0 | 0xdfffffffff |
      |-------------|
      1 | etc |
      |-------------|

      VTABLE[0] = 0xd3290dl means function-0 ( the compiler remembers Base::func
      as function-0 at COMPILE time) executable code can be found at this address
      (0xd3290dl ). But for Derived Class, Derived::func is also function-0
      because it is derived from Base. For that reason, both Base::func and
      Derived::func have the same index. But, Derived::func implementation is
      different. So the compiler inserts different address to figure out where
      Derived::func code be found ( 0xdfffffffff for our example) Using different
      addresses, the program can actually look up in the table and figure out the
      location of the function implementation at RUN time.

      Quiz : What value should you expect for VTABLE[0] for Derived ? if Derived
      does not over write Base:func.
      Answer: 0xd3290dl or the same base VTABLE[0] for Base because both have the
      same code.

      Quiz 2:

      Derived* de = new Derived;
      Base* ba = (Base*) de;
      ba->func();

      Question: What should "ba->func()" be ? Derived::func or Base::func ?
      Answer: Derived::func because type casting does not change the VTABLE, so
      the address is still pointing to Derived::func.


      Things to Ponder
      ============
      1. If there is only one VTABLE and only one Executable code for each method,
      How does multiple-instances share the code ?
      2. How do you solve the problem with Multiple-Inheritance ?
      Repeated-Multiple-Inheritances ? or Cyclic?

      Ok this is as far as I can go without too much detail. It would be better
      for you to pick up a Compiler text book and look up under OO implementation.
      There are many ways to implement it and done differently depending on the
      lang spec. Trust Me, it is very confusing especially if you are thinking in
      C++. You need to start from a simple case and add a OO feature at time.
      Eventually, you will understand why VTABLE which is designed in a way solve
      a number of problems. Finally, you will understand why certain OO feature
      can't be done.


      "John Harrison" <john_andronicu s@hotmail.com> wrote in message
      news:bdgmlq$t7s 2s$1@ID-196037.news.dfn cis.de...[color=blue]
      >
      > "Kapil Khosla" <khoslakapil@ya hoo.com> wrote in message
      > news:919aa2da.0 306262147.5eba0 d2d@posting.goo gle.com...[color=green]
      > > Dear all,
      > > I am trying to underlying implementation of virtual functions in C++.
      > > The way I understand polymorphism is
      > >
      > > class Base
      > > {
      > > public:
      > > virtual int func();
      > > };
      > >
      > > class Derived: public Base
      > > {
      > > public:
      > > virtual int func();
      > > }
      > >
      > > int Base::func()
      > > {
      > > printf("In Base\n");
      > > }
      > >
      > > int Derived::func()
      > > {
      > > printf("In Derived\n");
      > > }
      > >
      > > void poly_func(Base * x)
      > > {
      > > x->func();
      > > }
      > > int main()
      > > {
      > > Derived ob1;
      > > poly_func(&ob1) ;
      > > }
      > >
      > > Output :
      > >
      > > This will call the function in the derived class instead of the base
      > > class due to the virtual keyword in the base class with func().
      > >
      > >
      > >
      > >
      > > Now my question is how does C++ implement such mechanism.
      > > I read something about VTables in C++, that every class has a
      > > different VTable which contain the appropriate function to be called.
      > > So by pushing the pointer to the appropriate VTable you can figure out
      > > the function to be called.
      > >
      > >
      > > They said that at "run time" you would find out which object is really
      > > being called and thus we need VTables. I dont understand this point.
      > > In this case it is pretty obvious that &ob1 is being passed so
      > > compiler can figure out at compile time which real function is to be
      > > called based on the fact that the virtual keyword is there in the base
      > > class. Can you give me an example where the compiler would not be able
      > > to figure out the type of the object being passed at compile time and
      > > thus show me the need of VTables.
      > >
      > > I am not very familiar with OOPS concept so might not be aware of some
      > > basic concepts.
      > >
      > > Thanks a lot,
      > > Kapil[/color]
      >
      > Simple, suppose main and poly_func were in two different files. Then when
      > the compiler compiled poly_func it wouldn't know anything about main, so[/color]
      it[color=blue]
      > wouldn't know that poly_func was being called with a pointer to Derived.
      >
      > Or, what if you changed your code to this
      >
      > int main()
      > {
      > Base obj1;
      > Derived obj2;
      > poly_func(&obj1 );
      > poly_func(&obj2 );
      > }
      >
      > Now your poly_func function has to deal with both types of object. So the
      > same code has to decide whether to call Base::func or Derived::func, so[/color]
      the[color=blue]
      > decision must be made at run time.
      >
      > john
      >
      >[/color]


      Comment

      Working...