How does C ++ implement polymorphism inside?

Dear sir!

I have to tell you what I know and what I don’t know about the question asked, so that you can turn to a weak area of ​​my understanding.

I know that C ++ implements polymorphism using Vtable, which is an array of pointers, each pointer points to a virtual function of the class, each class in the hierarchy has a vtable. now suppose i have a class

class person { char name[20]; public: person(char* pname) { strcpy(name,pname); } virtual void show() { cout<<"inside person show method, Name: "<<name; } }; class teacher:public person { int scale; teacher(char*pname, int s):person(pname) { scale=s; } void show() { cout<<"inside the teacher show method, Scale: "<<scale; } }; 

Now suppose I write in the main program

 person *ptr; ptr=new teacher(16,"Zia"); ptr->show(); 

now i'm confused at this point, the call will go to the show function of the base class, now since it is a virtual function, so inturn calls the corresponding function. I know that I am not right here. I am confused by what will be the sequence of calls. What role does Vtable play and how does it work, please specify.

+6
c ++ oop
source share
4 answers

I think you should pay attention to Stanley B. Lippman's book, An Internal Model of a C ++ Object .

Let's look at the internal presentation for your classes:

Virtual table for man and teacher

 |---------------| +---> |------------------------| | name | | | "type_info" for person | |---------------| | |------------------------| |__vptr__person |--+ | "person::~person" | |---------------| |------------------------| person p; | "person::show" | |------------------------| |----------------| +---> |-------------------------| |person subobject| | | "type_info" for teacher | |----------------| | |-------------------------| |__vptr__teacher |--+ | "teacher::~teacher" | |----------------| |-------------------------| teacher t; | "teacher::show" | |-------------------------| 

In general, we do not know the exact type of ptr address objects with every show () call. However, we know that through ptr we can access the virtual table associated with the class of the object.

Although we do not know which instance of show () is being called, we know that each instance address is contained in slot 2.

This information allows the compiler to internally convert the call to

 ( *ptr->vptr[ 2 ] )( ptr ); 

In this transformation, vptr is the internally created virtual table pointer inserted into each class object, and 2 represents the show () assigned slot in the virtual table associated with the point hierarchy. The only thing we need to do at runtime is to compute the dynamic type ptr (and the corresponding vtable) using RTTI.

+6
source share

Since show declared virtual in the person class, the compiler will not hard-code the method call, as it would for a non-virtual method, instead, it will compile the search in V- to get the correct function.

So ptr->show() will be compiled as ptr->vtable['show']() , which means "search for a function pointer that matches the show method and execute it."

Since ptr points to an object of the teacher class at run time, the vtable slot for show contains a pointer to the show method in the teacher class. That is why the correct method is executed.

In fact, the search in the V-table is not performed using strings, but using the numerical identifiers of the method to be as fast as possible.

+8
source share

C ++ does not define polymorphism implementations, not even vtable . This is up to the compilers.
One possible implementation option is the one mentioned by Vincent Robert .

+4
source share

The standard does not say anything about how to implement polymorphism. One vtbl class and one object one vptr is the most popular way. I hope the following pseudo code will be helpful.

 typedef struct { void (*show)(void* self); // more } person_vtbl; typedef struct { person_vtbl* vtbl; char name[20]; } person; void person_show(void* self) { cout<<"inside ... "<<static_cast<person*>(self)->name; } // more static person_vtbl person_vtbl_ = { &person_show }; // vtbl for person class void person_ctor(void* self, char const* name) { person* p = static_cast<person*>(self); strcpy(p->name, name); p->vtbl = &person_vtbl // vptr of person object } typedef struct { person base; int scale; } teacher; void teacher_show(void* self) { cout<<"inside the tearch ... "<<static_cast<teacher*>(self)->scale; } static person_vtbl teacher_vtbl_ = { &teacher_show }; void teacher_ctor(void* self, char const* name, int s) { teacher* t = static_cast<teacher*>(self); person_ctor(&t->base, name); // construct base part t->scale = s; // construct teacher part t->vtbl = &teacher_vtbl_; // vptr of teacher object } // construct teacher : // person* ptr = new teacher("Zia", 16); teacher* tmp = static_cast<teacher*>( malloc( sizeof *tmp ); teacher_ctor(tmp, "Zia", 16); // vptr of tmp points to teacher_vtbl_ person* ptr = &tmp->base; // call virtual function though pointer // ptr->show() ptr->vptr->show(ptr); // call teacher_show(ptr); 
+3
source share

All Articles