Problems encountered when using virtual function table pointers to call virtual functions

Problems encountered when using virtual function table pointers to call virtual functions

Define a Father class, the code is as follows:

class Father {
public:
virtual void func1() {cout << "Father::func1" << endl;}
virtual void func2() { cout << "Father::func2" << endl; }
virtual void func3() { cout << "Father::func3" << endl; }
void func4() { cout << "非虚函数:Father::func4" << endl; }
public:
int x = 200;
int y = 300;
static int z;
};

typedef void (*func_t)(void);

int main(void){

Father father;


cout << "对象father地址:" <<(int)&father << endl;
int* vptr = (int*)*(int*)(&father);//函数指针,int*类型
cout << "vptr:" << vptr << endl;

//((void (*)(void))vptr)(); wrong

((void(*)(void))*(vptr))();

((func_t) * (vptr + 0))();
((func_t) * (vptr + 1))();
((func_t) * (vptr + 2))();

​ return 0;

}

Explanation: Take the address of the father object to get an address, because the value stored in the address is a virtual function table pointer, and the function pointer occupies four bytes, so the address is converted to (int *) type to tell the compiler memory size, Then dereference to get the virtual function table pointer, and finally convert to (int *) type, get the virtual function table pointer, this time is (int *) type, and finally call the virtual function through this int * type pointer, how transfer? First change the type of the pointer, because the return value of the virtual function pointed to by the pointer is empty.

So define a type

typedef void(*func_t)(void);

Then write the code ((func_t) * (vptr + 0)) (); You can call the virtual function, that is, first dereference the pointer of the virtual function table to get the pointer of the virtual function. Note here: distinguish between the pointer of the virtual function table and the virtual function pointer! Otherwise, an error will occur, and it needs to be dereferenced twice here! The first is to dereference & father to get the virtual function table pointer, and then to dereference the virtual function table pointer to get the virtual function pointer.

So it is very clear to call virtual functions without custom types. The code should be written like this
: ((void (*) (void))) * (vptr)) ();
Never call ((void (*) (void))) (vptr)) (); It is a joke to confuse the pointer of the virtual function table with the pointer of the virtual function.

Mainly understand the concept of virtual function table pointer!

Guess you like

Origin www.cnblogs.com/Ybossy/p/12737069.html