さらにもうひとつクラスを作って3つのクラスを継承するように
してみた。
#include<windows.h>
#include<stdio.h>
class Base1
{
int a;
public:
Base1() { a = 0x12345678; };
virtual int get_a();
};
class Base2
{
int b;
public:
Base2() { b = 0xabcdef01; };
virtual int get_b();
};
class Base3
{
int d;
public:
Base3() { d = 0xace0bdf2; };
virtual int get_d();
};
class MyClass : public Base1, public Base2, public Base3
{
int c;
public:
MyClass() { c = 0x1a2b3c4d; };
virtual int get_c();
};
int Base1::get_a()
{
return a;
}
int Base2::get_b()
{
return b;
}
int Base3::get_d()
{
return d;
}
int MyClass::get_c()
{
return c;
}
int main(void) {
MyClass *mc;
int a, b, c, d;
mc = new MyClass();
a = mc->get_a();
b = mc->get_b();
c = mc->get_c();
d = mc->get_d();
printf("a : %8.8X b : %8.8X c : %8.8X d: %8.8X(%d)\n", a, b, c, d, sizeof(MyClass));
delete mc;
return 0;
} |
クラスMyClassのサイズは、28バイト。
デバッガで確認すると、以下のとおり。
00032B68 D8 60 40 00 78 56 34 12
00032B70 D4 60 40 00 01 EF CD AB
00032B78 D0 60 40 00 F2 DB E0 AC
00032B80 4D 3C 2B 1A |
vftableのアドレス、変数 int a
vftableのアドレス、変数 int b
vftableのアドレス、変数 int d
変数 int c
となっていることがわかる。
3つのvftableは以下のとおり。
004060D0 1E 10 40 00 get_d のアドレス
004060D4 0F 10 40 00 get_b のアドレス
004060D8 00 10 40 00 get_a のアドレス
004060DC 2D 10 40 00 get_c のアドレス |
以前、ecxへインスタンスへのアドレスをセットしてから関数をコールすると書いたが、
get_bおよびget_dを呼び出す際は、インスタンスへのアドレス+8、
インスタンスへのアドレス+16したアドレスをecxにセット後、コールしている。
つづく・・・