Virtual Functions

Hi All,
I am running following code

class A
{
public:
virtual const char* GetName() { return "A"; }
};

class B: public A
{
public:
virtual const char* GetName() { return "B"; }
};

class C: public B
{
public:
virtual const char* GetName() { return "C"; }
};

class D: public C
{
public:
virtual const char* GetName() { return "D"; }
};

int main()
{
C cClass;
A &rBase = cClass;
cout << "rBase is a " << rBase.GetName() << endl;

return 0;
}

I got this example from:http://www.learncpp.com/cpp-tutorial/122-virtual-functions/

When I was debugging this code, when rBase.GetName() line in main() was called, I was expecting the debugger to call Base class A getname() method first. Since it is Virtual it should have then gone to B and C. But this is not wat actually happened and the debugger went straight away to the C::GetName() . Can someone please explain why since that's how virtual functions work
please explain why since that's how virtual functions work

Sure, I'll explain why: Because that's not how virtual functions work.

B, C and D inherit from A.

therefore B, C and D all know about A, but they don't know about each other.
A virtual member function is a member function that can be redefined in a derived class.
Since there is a reference of type Class A and that is assigned to the Class C, that will only contain the members of Class A and only know about Class A, not B.
Virtual table resolves the Class C GetName() function pointer at runtime, since the Class A GetName() has been overridden by virtual keyword.
virtual functions calls does not get binded at compile time. Program decided which function to call at the runtime. Usually this is achieved by adding hidden pointer to virtual call table to the object. When object is created it will be initialized by pointer to virtual table related to his actual class. Further access to virtual function through pointers or references to the base class call methods through virtual table to ensure that method of object actual class is called.

In your case your function call can internally look like: rBase.__vtable -> GetName();
Last edited on
First, we instantiate a C class object. rBase is an A pointer, which we set to point to the A portion of the C object. Finally, we call rBase.GetName(). rBase.GetName() evaluates to A::GetName(). However, A::GetName() is virtual, so the compiler will check all the classes between A and C to see if it can find a more-derived match. First, it checks B::GetName(), and finds a match. Then it checks C::GetName() and finds a better match. It does not check D::GetName() because our original object was a C, not a D. Consequently, rBase.GetName() resolves to C::GetName().
Last edited on
This is the explaination given by author of the post. . As per him the call should first go to A and then from there to C. Is this incorrect. . Can someone point to the correct explanation as I want to really get this right
First, we instantiate a C class object. rBase is an A pointer, which we set to point to the A portion of the C object.
Mostly correct
Finally, we call rBase.GetName(). rBase.GetName() evaluates to A::GetName().
Incorrect! It is virtual function and it does not binds in compile time. It will be transformed into call though virtual table pointer as I posted earlier. Actually compiler might not even know about classes B, C, D etc. existence at all! In theory you can use classes derived from your but loaded through dinamic libraries.
Compiler does not know what original object was, all nessesary information is stored inside object itself and resolved at runtime.

learncpp gives incorrect information here, but corrects itself in http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/

Also:
http://en.wikipedia.org/wiki/Virtual_method_table
Last edited on
Topic archived. No new replies allowed.