Virtual method implementation in C++

K

Kapil Khosla

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
 
J

John Harrison

Kapil Khosla said:
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

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
 
M

Min

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.
 

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

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top