tags:

views:

110

answers:

4

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?

+7  A: 

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.

Martin B
Nice one !!! :). Also +1 for RTTI.
Incognito
+1  A: 

You can access vpointer and even you can call any virtual method in class through vpointer. But remember this is EVIL.

Example :

class A
{
public:
    void f1()
    {
        cout<<"bbb"<<endl;;
    }
    virtual void f2()
    {
        cout<<"ccc"<<endl;;
    }
    virtual void f3()
    {
        cout<<"ddd"<<endl;;
    }
};

and call in main

A a;

typedef void (__thiscall* foo)();
(*(foo)((void**)(((void**)(&a))[0]))[1])();

It will access vpointer and then will go by index and will execute the second method in vTable which is f3().

Also note to use RTTI as already suggested.

Incognito
Wow !!!! It is brainbraking but great! Never would like to have such questions on interview.
And how does this answer the concrete question?
Péter Török
+4  A: 

Yes, it's quite possible to do - use dynamic_cast. This is pretty crappy question - a slightly better one might be "How is dynamic_cast implemented?" but really if asked either at an interview I'd have to wonder about the nous of the interviewer. Being a good, or even a great, C++ programmer does not depend on knowing nitpicking implementation details like this, but these are of course easy questions for second-raters to ask.

anon
+2  A: 

Check the typeid() function.

Dummy00001