I was recently on an interview for a position where C/C++ is the primary language and during one question I was told that it's possible to use the vtable to determine which class in a hierarchy a base pointer actually stores.
So if, for example you have
class A
{
public:
A() {}
virtual ~A() {}
virtual void method1() {}
};
class B : public A
{
public:
B() {}
virtual ~B() {}
virtual void method1() {}
};
and you instantiate A * pFoo = new B()
, is it indeed possible to use the vtable to determine whether pFoo contains a pointer to an instance of A or B?
For every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.
A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this vTable is simply a Function Pointer that points to the most-derived function accessible by that class ie the most Base Class.
Vtable is like an array of function pointer. Vtable and Vptr is creating at compile time which will get memory in run time and vtable entries are virtual function addresses . Every object of a class containing a virtual function will have an extra pointer which is pointing to Virtual Table is known as virtual pointer.
To implement virtual functions, C++ uses a special form of late binding known as the virtual table. The virtual table is a lookup table of functions used to resolve function calls in a dynamic/late binding manner.
This is obviously implementation dependent but, on most implementations, the in-memory representation of an object of class A
or B
will start with a pointer to the vtable. You can look at this vtable pointer, compare it to vtable pointers for objects that you know to be of class A
or B
, and determine the class of the object in that way.
To illustrate (of course this is anything but good style):
A *pFoo=new B(); // pointer to object of unknown class (either A or B)
A a; // Object known to be of class A
B b; // Object known to be of class B
void *vptrA=*((void **)&a); // Pointer to vtable of class A
void *vptrB=*((void **)&b); // Pointer to vtable of class B
void *vptrFoo=*((void **)pFoo); // Pointer to vtable of unknown object
if(vptrFoo==vptrA)
printf("Class A\n");
else
printf("Class B\n");
Important: This is only an illustration of how most implementations work; besides being implementation dependent, this technique breaks down in the presence of multiple inheritance. You should never do anything like this in production code; use RTTI instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With