NVIDIA Interview Question
InternsCountry: United States
Interview Type: Phone Interview
Actually, I will be very wrong if I say C++ implements polymorphism like above code snippet. But the above code shows a small glimpse about the trick behind virtual function. There are a lot of things which "C++" compiler does behind the scene.
This code seems like overloading. A function name with two different arguments.
Polymorphism is a concept to describe a function of class which behave different when referred by different subclass object.
typedef struct {
//some field
int a;
}StructTwo;
typedef struct {
//some field
}StructOne;
typedef struct {
int type;
union {
StructOne one;
StructTwo two;
};
}BaseStruct;
void foo(BaseStruct b){
switch (b.type) {
case 1:
//do something on b.one
break;
case 2:
//do something else b.two
break;
}
}
int main(){
BaseStruct base;
StructOne one;
StructTwo two;
base.type=1;
base.one=one;
foo(base);
base.type=2;
base.two=two;
foo(base);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef void (*fnptr_t)(void*);
struct A {
const fnptr_t* vtable;
int field_A;
};
void A_vfunc_0(void* obj)
{
struct A* this = (struct A*)obj;
printf("%s field_A = %d\n", __FUNCTION__, this->field_A);
}
// B inherent from A
struct B {
struct A parent;
int field_B;
};
void B_vfunc_0(void* obj)
{
struct B* this = (struct B*)obj;
A_vfunc_0(this);
printf("%s field_B = %d\n", __FUNCTION__, this->field_B);
}
// vtables for A & B
const fnptr_t vtable_A[] = { A_vfunc_0 };
const fnptr_t vtable_B[] = { B_vfunc_0 };
// constructors for A & B
void initA(struct A* obj, int v)
{
obj->field_A = v;
obj->vtable = vtable_A;
}
struct A* createA(int v)
{
struct A* r = (struct A*) malloc(sizeof(struct A));
initA(r, v);
return r;
}
void initB(struct B* obj, int v0, int v1)
{
initA(&(obj->parent), v0);
obj->field_B = v1;
obj->parent.vtable = vtable_B;
}
struct B* createB(int v0, int v1)
{
struct B* r = (struct B*) malloc(sizeof(struct B));
initB(r, v0, v1);
return r;
}
// call virtual functions
void invoke_vfunc(struct A* obj, int idx)
{
obj->vtable[idx](obj);
}
int main(int argc, char** argv)
{
struct A* objA = createA(1);
struct A* objB = (struct A*)createB(2, 3);
printf("call A func:\n");
invoke_vfunc(objA, 0);
printf("call B func:\n");
invoke_vfunc(objB, 0);
free(objA);
free(objB);
return 0;
}
- Manish January 08, 2014