Click here to Skip to main content
16,004,678 members
Please Sign up or sign in to vote.
2.33/5 (2 votes)
See more:
I am just trying to understand the virtual fns. concept.

I know that if I have a virtual fn. in a base class and its overridden fn. in derived class then based upon the address of base/derived object stored in the base class pointer the fns. will be called.


In the below code I had kept the show() fn. as virtual and it used to call properly the base and derived classes show().

But when I removed the virtual tag from show() then why does not it calls derived show() inspite of base class pointer having address of derived class object?

C++
class base
{
public:
    base()
    {
        printf("Base Cons\n");
    }

    void show()
    {
        printf("Base Show\n");
    }
};

class der: public base
{
public:
    der()
    {
        printf("Der Cons\n");
    }

    void show()
    {
        printf("Der Show\n");
    }
};

void yahoo(base* bpointer)
{
    printf("Address in base pointer = %u\n",bpointer);
    bpointer->show();
}

int _tmain(int argc, _TCHAR* argv[])
{
    class base bobj, *bptr;
    class der dobj;

    bptr = & bobj;
    printf("Base obj adress = %u\n",&bobj);
    yahoo(bptr);

    bptr = &dobj;
    printf("Base obj adress = %u\n",&dobj);
    yahoo(bptr);

    return 0;
}



Output of code:
C++
Base Cons
Base Cons
Der Cons
Base obj adress = 1245027
Address in base pointer = 1245027
Base Show
Base obj adress = 1245003
Address in base pointer = 1245003
Base Show
Posted
Comments
#realJSOP 8-Nov-11 7:56am    
Why did you feel compelled to abbreviate the word "functions" every time you used it? It makes your question MUCH harder to read. Write complete words and snetences. To do otherwise is an insult to the rest of us.
rupeshkp728 8-Nov-11 8:05am    
I will take care of this in future.
Chuck O'Toole 8-Nov-11 8:23am    
Wow, popular. Within a few minutes you have 3 of us colliding on answers. Must be a good question then.
Chuck O'Toole 8-Nov-11 8:25am    
More wow, make that 5 answers. We are all jumping on this one :)
Malli_S 8-Nov-11 8:30am    
There are so many others, might already be running to jump ! :)

You need the keyword virtual in your base class.
If you omit this. The functions are not overridden only hidden.
C++
virtual void show()


This is because your pointer is a base*, as the function 'show' is not virtual, there is no need for the compiler to search for an overridden member.
 
Share this answer
 
v2
Comments
rupeshkp728 8-Nov-11 8:31am    
It cleared my doubt to many extent.
Every object of der also automatically is of the type base. It inherits everything, but may overload methods.

If show() is not virtual: The type of the pointer used to access the method determines which overload of the method will be used. You use a pointer of the type base*, so it will be base::show() that will be called.

If show() is virtual: The actual type of the object determines which method will be called, no matter wether you access it over a pointer to the baseclass or not. In this case der::show() would be called.

But why should the address of an object change? The object of base is at a certain address and the object of der at another one. The derived object can be seen as an object of base as well as one of der, but it still is at the same location.
 
Share this answer
 
Comments
rupeshkp728 8-Nov-11 8:32am    
Your reply clears all the doubt.
Language wise, virtual functions allow for objects of the derived type to be accessed as if they were the base type and still have the proper functions in the derived class be called.

what you have here is a case where all of your references are using pointers that are declared to be pointers to the base class so, without virtual, it's not surprising that only base class functions are called.

There is some magic involved. In order to keep compiled code reasonably small and fast, the compiler looks at what it knows and doesn't know about a class and its functions. If the compiler can completely resolve the issue of "reference type" (the pointer or object) and the "member function" (by name / footprint) then the compiler can optimize the whole thing into a direct call to the code (setting "this" and letting the linker resolve the actual code location).

If the member function is virtual, then it cannot know exactly which member function to call directly so it has to use a jump table or dispatch vector type of call through data built into the object itself. That table exists for every object created so, to keep the table from being overly huge, only virtual functions are listed there.

So, with virtual, you get "indirect references through a dispatch table", without virtual, you get "direct calls to known member functions".

That should explain the behavior you see.
 
Share this answer
 
Comments
rupeshkp728 8-Nov-11 8:33am    
Your reply clears all the doubt.
The virtual function mechanism works on two things. Virtual Table (VTable) and Virtual Table Pointer (VPtr). To know how they works, you should know their purpose. The VTable serves as a list of address of all the virtual functions in the class. And VPtr is the pointer to the VTable of the class. Using these two, the dynamic linking of the function is done. i.e. the actual function call address is decided/resolved at the run time.

When you declare any function in class as virtual, the function address goes as an entry to virtual table. Every class has got it's own vtable and vptr (virtual pointer).
There are so many things for you to know about Virtual Functions. I've explained the things considering you're new to virtual concepts.

Better you can google out for these stuffs. For now you can have a look at this[^].
 
Share this answer
 
Comments
rupeshkp728 21-Nov-11 5:33am    
Thanks Malli.
The link provides a good explaination.
Malli_S 29-Nov-11 0:34am    
You welcome !
[no name] 26-Mar-12 5:05am    
Very good link Malli
Malli_S 27-Mar-12 1:17am    
Thank You... :)
C++
But when I removed the virtual tag from show() then why does not it calls derived show() inspite of base class pointer having address of derived class object?


Whole purpose of virtual keyword is for run time metamorphism . If function is not virtual it is not late binding. Decision is taken while compile time only which function should get called. You have created object of base class and at compile time compiler don't know exact address so it will call base class (or whichever object is created ) function.
 
Share this answer
 
Comments
Chuck O'Toole 8-Nov-11 8:28am    
I think your last comment is backwards, You have created object of base class and at compile time compiler don't know exact address so it will call base class (or whichever object is created ) function.. Don't you mean that the compiler does know the exact address (base)and, because it is not virtual, it calls the base class function directly?
Sergey Alexandrovich Kryukov 16-Nov-12 22:56pm    
Polymorphism which is not run-time is a myth. It was some discussion of it on CodeProject; I felt it was outrageous.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900