class Polygon {
protected:
int width, height;
public:
virtual int area()
{
return 0;
}
};
class Rectangle : public Polygon {
public:
int area()
{
return width * height;
}
};
class Triangle : public Polygon {
public:
int area()
{
return (width * height / 2);
}
};
class RectangleTriangle : public Rectangle, Triangle //RectangleTriangle <-- This class will have two Vtables for each base class
{
public:
int area()
{
return (2* 3/ 2);
}
};
int main() {
RectangleTriangle *rect = new RectangleTriangle();
Triangle trgl;
Polygon poly;
return 0;
}
Причина, по которой мы начинаем с vtables, заключается в том, что любой объект, который наследует виртуальную функцию, будет иметь указатель vtable, который в основном является статической переменной класса.Таким образом, каждый объект этого класса должен иметь ссылку на это местоположение vtable при создании объекта в куче.Таким образом, из указателя vtable мы в основном пытаемся получить сам объект.
0:000> x Win32Sample!RectangleTriangle*table*
00007ff7`81ed3288 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class
00007ff7`81ed3278 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class
0:000> !heap -srch 00007ff7`81ed3288 // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
_HEAP @ 1e5ed710000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
000001e5ed716620 0006 0000 [00] 000001e5ed716630 00021 - (busy)
Win32Sample!RectangleTriangle::`vftable'
0:000> !heap -srch 00007ff7`81ed3278 // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
_HEAP @ 1e5ed710000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
000001e5ed716620 0006 0000 [00] 000001e5ed716630 00021 - (busy)
Win32Sample!RectangleTriangle::`vftable'
UserPtr - это, по сути, начало блока памяти, возвращаемого менеджером кучи для нового оператора.Вот почему UserPtr не означает место в памяти, которое включает это значение, вместо этого оно является началом блока кучи, следовательно, в обеих таблицах значение одинаково 000001e5ed716630
0:000> dt Win32Sample!RectangleTriangle 000001e5ed716630
+0x000 __VFN_table : 0x00007ff7`81ed3278
+0x008 width : 0n0
+0x00c height : 0n0
+0x010 __VFN_table : 0x00007ff7`81ed3288
+0x018 width : 0n0
+0x01c height : 0n0
Мы не можем использовать команду s для поискауказатель vtable и объект в куче, потому что блоки кучи не являются смежными !!!