Memory implementation of member functions in C++
I read an article on virtual table in Wikipedia.
class B1
{
public:
void f0() {}
virtual void f1() {}
int int_in_b1;
};
class B2
{
public:
virtual void f2() {}
int int_in_b2;
};
used to derive the following class:
class D : public B1, public B2
{
public:
void d() {}
void f2() {} // override B2::f2()
int int_in_d;
};
After reading it I couldn't help but wonder how non virtual member functions are implemented in C++. Is there a separate table like the v-table in which all t开发者_StackOverflow中文版he function addresses are stored? If yes, what is this table called and what happens to it during inheritance?
If no then how does compiler understand these statements?
D * d1 = new D;
d1->f0(); // statement 1
How does compiler interpret that f0() is function of B1 and since D has publicly inherited D it can access f0(). According to the article the compiler changes statement 1 to
(*B1::f0)(d)
Non-virtual member functions are implemented like global functions that accept a hidden this
parameter. The compiler knows at compile time which method to call based on the inheritance tree, so there's no need for a runtime table.
Aside from this, I can only say that a normal member function is just a memory address within a class (I even believe every object of that class use the same "function pointer" in memory, but with their own variables). A v-table is a form of runtime redirection, as the compiler can't know what object exactly it is dealing with (obviously due to polymorphism).
Is there a separate table like the v-table in which all the function addresses are stored?
They are stored in the place where they are called.
Taking your example: As long as the f0 method is non-virtual, the compiler knows what's the address of it because there is only one possibility. Let the address be 0xABCD. Then the code
d1->f0(); // statement 1
is compiled to instructions:
// push onto the stack 'this' pointer, as you pointed out the address must
// be earlier translated from D class to B1 which is not presented here
push d1
call 0xABCD // call method at known address (jump to this address)
精彩评论