Sometimes you just need to see some codes / diagrams :) Please note that the standard does not mention this implementation detail.
First of all, let's see how to implement methods in C ++:
struct Base
{
void foo();
};
It looks like:
struct Base {};
void Base_foo(Base& b);
And in fact, when you look at the method call inside the debugger, you often see the argument thisas the first parameter. It is sometimes called an implicit parameter.
Now, to the virtual table. In C and C ++, there may be pointers to work with. Vtable is essentially a table of function pointers:
struct Base
{
int a;
};
void Base_set(Base& b, int i) { b.a = i; }
int Base_get(Base const& b) { return b.a; }
struct BaseVTable
{
typedef void (*setter_t)(Base&, int);
typedef int (*getter_t)(Base const&);
setter_t mSetter;
getter_t mGetter;
BaseVTable(setter_t s, getter_t g): mSetter(s), mGetter(g) {}
} gBaseVTable(&Base_set, &Base_get);
Now I can do something like:
void func()
{
Base b;
(*gBaseVTable.mSetter)(b, 3);
std::cout << (*gBaseVTable.mGetter)(b) << std::endl;
}
Now, to inheritance. Let me create another structure
struct Derived: Base {};
void Derived_set(Derived& d, int i) { d.a = i+1; }
struct DerivedBaseVTable
{
typedef void (*setter_t)(Derived&,int);
typedef BaseVTable::getter_t getter_t;
setter_t mSetter;
getter_t mGetter;
DerivedBaseVTable(setter_t s, getter_t g): mSetter(s), mGetter(g) {}
} gDerivedBaseVTable(&Derived_set, &Base_get);
And use:
void func()
{
Derived d;
(*gDerivedBaseVTable.mSetter)(d, 3);
std::cout << (*gDerivedBaseVTable.mGetter)(d) << std::endl;
}
?
, ? , :
| Derived |
| BaseA | BaseB |
| vpointer | field1 | field2 | padding? | vpointer | field1 | field2 | padding? |
, MostDerived 2 : BaseA BaseB.
() .
, , :
BaseA: vpointer, ,BaseB: vpointer, attributes, bodyDerived: vpointers (), ,
Derived is destructed: , , vpointersBaseB : ,BaseA : ,
, , , ++ , - . , - , .