- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
Contents">目录
C%AC%E7%89%B9%E6%80%A7-toc" name="tableOfContents" style="margin-left:40px">基本特性
Contents" style="margin-left:40px">构造函数
Contents" style="margin-left:40px">静态成员
Contents" style="margin-left:40px">常量成员
Contents" style="margin-left:40px">继承构造
Contents" style="margin-left:40px">继承(单)
Contents" style="margin-left:40px">继承(多)
Contents" style="margin-left:40px">继承(菱)
Contents" style="margin-left:40px">多态(单)
Contents" style="margin-left:40px">多态(多)
Contents" style="margin-left:40px">虚表(单)
Contents" style="margin-left:40px">虚表(多)
Contents" style="margin-left:40px">纯虚
Contents" />
C%AC%E7%89%B9%E6%80%A7" name="%E5%9F%BA%E6%9C%AC%E7%89%B9%E6%80%A7">基本特性
#include <iostream>
#include <Windows.h>
struct MyStruct
{
//public:
int age;
};
class Person
{
//private:
int age;
public:
int a;
int b;
//public:
// int c;
// int d;
// int e;
// int f;
// int g;
public:
static int ver;
public:
void SetData(int a, int b)
{
this->a = a;
this->b = b;
/*
0040105C 51 push ecx
0040106C 59 pop ecx
0040106D 89 4D F8 mov dword ptr [ebp-8],ecx
0040107A 8B 45 F8 mov eax,dword ptr [ebp-8]
0040107D 8B 4D 08 mov ecx,dword ptr [ebp+8]
00401080 89 08 mov dword ptr [eax+0],ecx
00401082 8B 45 F8 mov eax,dword ptr [ebp-8]
00401085 8B 4D 0C mov ecx,dword ptr [ebp+0Ch]
00401088 89 48 04 mov dword ptr [eax+4],ecx
*/
}
void _cdecl SetDataa(int a)
{
this->a = a;
/*
004010D1 8B 45 08 mov eax,dword ptr [ebp+8]
004010D4 8B 4D 0C mov ecx,dword ptr [ebp+0Ch]
004010D7 89 08 mov dword ptr [eax],ecx
*/
}
void _stdcall SetDatab(int b)
{
this->b = b;
/*
00401111 8B 45 08 mov eax,dword ptr [ebp+8]
00401114 8B 4D 0C mov ecx,dword ptr [ebp+0Ch]
00401117 89 48 04 mov dword ptr [eax+4],ecx
0040112D C2 08 00 ret 8
*/
}
void _fastcall SetDataab(int a, int b)
{
this->a = a;
this->b = b;
/*
0040110D 89 55 F8 mov dword ptr [ebp-8],edx
00401110 89 4D EC mov dword ptr [ebp-14h],ecx
0040111D 8B 45 EC mov eax,dword ptr [ebp-14h]
00401120 8B 4D F8 mov ecx,dword ptr [ebp-8]
00401123 89 08 mov dword ptr [eax],ecx
00401125 8B 45 EC mov eax,dword ptr [ebp-14h]
00401128 8B 4D 08 mov ecx,dword ptr [ebp+8]
0040112B 89 48 04 mov dword ptr [eax+4],ecx
*/
}
public:
// 函数重载
Person()
{
a = 1;
b = 2;
}
Person(int a)
{
this->a = a;
}
Person(int a, int b)
{
this->a = a;
this->b = b;
}
~Person()
{
a = 0;
b = 0;
}
};
int Person::ver = 1;
int g_Num = 1;
Person g_Obj;
void SetData(int* a, int* b)
{
*a = 1;
*b = 1;
}
void classParam1(Person per)
{
}
void classParam2(Person* p)
{
}
void classParam2()
{
}
Person retClass()
{
Person obj;
return obj;
}
Person* retClassptr()
{
return NULL;
}
int main()
{
Person obj;
Person* p = &obj;
Person obj1;
Person obj2;
// 成员偏移
{
p->a = 1;
p->b = 2;
printf("%d \r\n", &((Person*)NULL)->b);
/*
0x0019FED4 00 00 00 00 ....
0x0019FED8 00 00 00 00 ....
Person obj = { 0 };
004010BF 33 C0 xor eax,eax
004010C1 89 45 F0 mov dword ptr [ebp-10h],eax
004010C4 89 45 F4 mov dword ptr [ebp-0Ch],eax
Person* p = &obj;
004010C7 8D 45 F0 lea eax,[ebp-10h]
004010CA 89 45 E4 mov dword ptr [ebp-1Ch],eax
p->a = 1;
004010CD 8B 45 E4 mov eax,dword ptr [ebp-1Ch]
004010D0 C7 00 01 00 00 00 mov dword ptr [eax+0],1
p->b = 2;
004010D6 8B 45 E4 mov eax,dword ptr [ebp-1Ch]
004010D9 C7 40 04 02 00 00 00 mov dword ptr [eax+4],2
*/
int a = 2;
int b = 2;
SetData(&a, &b);
int a1 = 2;
int b1 = 2;
SetData(&a1, &b1);
}
// 调用约定
{
// this call
obj1.SetData(1, 1);
obj2.SetData(2, 2);
/*
this call
obj1.SetData(1, 1);
0040128B 6A 01 push 1
0040128D 6A 01 push 1
0040128F 8D 4D A4 lea ecx,[ebp-5Ch] ****
00401292 E8 B9 FD FF FF call 00401050
obj2.SetData(2, 2);
00401297 6A 02 push 2
00401299 6A 02 push 2
0040129B 8D 4D 94 lea ecx,[ebp-6Ch] ****
0040129E E8 AD FD FF FF call 00401050
*/
// _cdecl
obj1.SetDataa(1);
/*
004012E3 6A 01 push 1
004012E5 8D 45 A4 lea eax,[ebp-5Ch]
004012E8 50 push eax
004012E9 E8 C2 FD FF FF call 004010B0
004012EE 83 C4 08 add esp,8
*/
// _stdcall
obj1.SetDatab(1);
/*
00401331 6A 01 push 1
00401333 8D 45 A4 lea eax,[ebp-5Ch]
00401336 50 push eax
00401337 E8 B4 FD FF FF call 004010F0
*/
// _fastcall
obj1.SetDataab(1, 2);
/*
0040139C 6A 02 push 2
0040139E BA 01 00 00 00 mov edx,1
004013A3 8D 4D A4 lea ecx,[ebp-5Ch]
004013A6 E8 45 FD FF FF call 004010F0
*/
}
// 成员内存
{
printf("%d \r\n", sizeof(Person));
p->a = 1;
p->b = 2;
p->ver = 3;
/*
004013D2 mov eax,dword ptr [ebp-1Ch]
004013D5 mov dword ptr [eax+0],1
004013DB mov eax,dword ptr [ebp-1Ch]
004013DE mov dword ptr [eax+4],2
004013E5 mov dword ptr ds:[00407000h],3
*/
obj1.ver = 1;
obj2.ver = 2;
Person::ver = 3;
/*
004013D7 mov dword ptr ds:[00407000h],1
004013E1 mov dword ptr ds:[00407000h],2
004013EB mov dword ptr ds:[00407000h],3
*/
}
// 参数传递
{
classParam1(obj);
/*
int a;
int b;
00401435 mov eax,dword ptr [ebp-0Ch]
00401438 push eax
00401439 mov ecx,dword ptr [ebp-10h]
0040143C push ecx
0040143D call 00401210
00401442 add esp,8
*/
/*
public:
int a;
int b;
public:
int c;
00401438 sub esp,0Ch
0040143B mov eax,esp
0040143D mov ecx,dword ptr [ebp-14h]
00401440 mov dword ptr [eax+0],ecx
00401442 mov edx,dword ptr [ebp-10h]
00401445 mov dword ptr [eax+4],edx
00401448 mov ecx,dword ptr [ebp-0Ch]
0040144B mov dword ptr [eax+8],ecx
0040144E call 00401210
00401453 add esp,0Ch
*/
/*
public:
int a;
int b;
public:
int c;
int d;
int e;
int f;
int g;
0040145F sub esp,1Ch
00401462 mov ecx,7
00401467 lea esi,[ebp-24h]
0040146A mov edi,esp
0040146C rep movs dword ptr es:[edi],dword ptr [esi]
0040146E call 00401210
00401473 add esp,1Ch
*/
classParam2(&obj);
/*
004014B6 lea eax,[ebp-24h]
004014B9 push eax
004014BA call 00401250
004014BF add esp,4
*/
}
// 对象返回
{
Person obj = retClass();
/*
public:
int a;
int b;
00401564 call 00401290
00401569 mov dword ptr [ebp+FFFFFEB4h],eax
0040156F mov dword ptr [ebp+FFFFFEB8h],edx
00401575 mov eax,dword ptr [ebp+FFFFFEB4h]
0040157B mov ecx,dword ptr [ebp+FFFFFEB8h]
00401581 mov dword ptr [ebp-7Ch],eax
00401584 mov dword ptr [ebp-78h],ecx
*/
/*
public:
int a;
int b;
public:
int c;
00401585 lea eax,[ebp+FFFFFE8Ch]
0040158B push eax
0040158C call 00401290
00401591 add esp,4
00401594 mov ecx,dword ptr [eax+0]
00401596 mov dword ptr [ebp+FFFFFEA0h],ecx
0040159C mov edx,dword ptr [eax+4]
0040159F mov dword ptr [ebp+FFFFFEA4h],edx
004015A5 mov eax,dword ptr [eax+8]
004015A8 mov dword ptr [ebp+FFFFFEA8h],eax
004015AE mov ecx,dword ptr [ebp+FFFFFEA0h]
004015B4 mov dword ptr [ebp+FFFFFF74h],ecx
004015BA mov edx,dword ptr [ebp+FFFFFEA4h]
004015C0 mov dword ptr [ebp+FFFFFF78h],edx
004015C6 mov eax,dword ptr [ebp+FFFFFEA8h]
004015CC mov dword ptr [ebp+FFFFFF7Ch],eax
*/
}
// 构造析构
{
// 局部对象
{
Person obj111;
printf("Test\r\n");
/*
00401695 lea ecx,[ebp-98h]
0040169B call Person::Person (0401000h)
004016A0 push offset string "Test\r\n" (0405160h)
004016A5 call printf (04017C0h)
004016AA add esp,4
004016AD lea ecx,[ebp-98h]
004016B3 call Person::~Person (0401060h)
*/
}
// 堆对象
{
Person* pObj = new Person;
int a = 1;
if (pObj)
{
delete pObj;
pObj = NULL;
}
pObj = (Person*)malloc(sizeof(Person));
if (pObj)
{
free(pObj);
pObj = NULL;
}
}
}
// 数据权限
{
MyStruct str;
Person obj;
str.age = 18;
//编译器限制
//obj.age = 18;
int* p = (int*)&obj;
obj.a = 11;
obj.b = 2;;
p[0] = 0xCC;
p[1] = 0xCC;
p[2] = 0xCC;
char* pp = (char*)&obj;
/*
char
int
short
CC XX XX XX
CC CC CC CC
CC CC XX XX
*/
pp[0] = 0x11;
*(int*)(pp + 4) = 0x22222222;
*(short*)(pp + 8) = 0x3333;
}
return 3;
}
构造函数
#include <iostream>
class Person
{
public:
int m_Age;
int m_Height;
public:
char* m_Addr;
public:
// 构造函数
//Person() = delete;
//Person(const Person&) = delete;
Person()
{
this->m_Age = 0;
this->m_Height = 0;
this->m_Addr = 0;
}
Person(int nAge)
{
this->m_Age = nAge;
this->m_Height = 0;
this->m_Addr = 0;
}
Person(int nAge, int nHeight)
{
this->m_Age = nAge;
this->m_Height = nHeight;
this->m_Addr = 0;
}
Person(char nAge, int nHeight = 0, int nAddr = 0)
{
this->m_Age = nAge;
this->m_Height = nHeight;
this->m_Addr = (char*)nAddr;
}
Person(const Person& obj)
{
// 深拷贝 与 浅拷贝
this->m_Age = obj.m_Age;
this->m_Height = obj.m_Height;
if (obj.m_Addr != NULL)
{
this->m_Addr = (char*)malloc(20);
}
else
{
this->m_Addr = obj.m_Addr;
}
}
~Person()
{
if (this->m_Addr != NULL)
{
free(this->m_Addr);
this->m_Addr = NULL;
}
}
};
// 函数重载
void Fun()
{
}
void Fun(int a)
{
}
int main()
{
Person obj1;
Person obj2(18);
Person obj3(18, 180);
//Person obj4(18, 180, 10);
/*
this call -> lea ecx, xx
004010B9 lea ecx,[obj1]
004010BC call Person::Person (0401060h)
004010C1 push 12h
004010C3 lea ecx,[obj2]
004010C6 call Person::Person (0401000h)
004010CB push 0B4h
004010D0 push 12h
004010D2 lea ecx,[obj3]
004010D5 call Person::Person (0401030h)
*/
Person obj4(obj3);
/*
004010DA mov eax,dword ptr [obj3]
004010DD mov ecx,dword ptr [ebp-14h]
004010E0 mov dword ptr [obj4],eax
004010E3 mov dword ptr [ebp-1Ch],ecx
*/
Person obj5;
obj5 = obj4;
/*
004010E6 lea ecx,[obj5]
004010E9 call Person::Person (0401060h)
004010EE mov eax,dword ptr [obj4]
004010F1 mov ecx,dword ptr [ebp-1Ch]
004010F4 mov dword ptr [obj5],eax
004010F7 mov dword ptr [ebp-24h],ecx
*/
Person obj6;
obj6.m_Addr = (char*)malloc(20);
Person obj7(obj6);
Person obj8(1, 2);
return 0;
}
静态成员
#include <iostream>
class Person
{
public:
int m_A;
public:
// 静态成员
// 静态变量
static int ver;
// 静态函数
static int Add(int a, int b)
{
//m_A = 1;
ver = 3;
return a + b;
}
};
int Person::ver = 1;
int main()
{
Person obj1;
Person obj2;
obj1.m_A = 1;
obj2.m_A = 1;
obj1.ver = 2;
obj2.ver = 3;
Person::ver = 4;
/*
00401029 mov dword ptr [Person::ver (0404000h)],2
00401033 mov dword ptr [Person::ver (0404000h)],3
0040103D mov dword ptr [Person::ver (0404000h)],4
*/
obj1.Add(1, 2);
obj2.Add(2, 3);
Person::Add(3, 4);
/*
00401067 push 2
00401069 push 1
0040106B call Person::Add (0401000h)
00401070 add esp,8
00401073 push 3
00401075 push 2
00401077 call Person::Add (0401000h)
0040107C add esp,8
0040107F push 4
00401081 push 3
00401083 call Person::Add (0401000h)
00401088 add esp,8
*/
return 0;
}
常量成员
#include <iostream>
class Person
{
public:
int m_A;
public:
const int m_B;
public:
mutable int m_C;
public:
Person(int a, int b) : m_A(a), m_B(b)
{
}
public:
void GetInfo() const
{
//m_A = 1;
//m_B = 2;
m_C = 0xCC;
}
};
Person g_Obj(0xCC, 0xFF);
int main()
{
g_Obj.m_A = 1;
//g_Obj.m_B = 2;
Person* p = &g_Obj;
//p->m_B = 2;
int* pp = (int*)&g_Obj;
pp[1] = 2;
g_Obj.GetInfo();
Person obj1(1,2);
Person obj2(2,3);
/*
00401049 lea ecx,[obj1]
0040104C call Person::Person (0401000h)
00401051 lea ecx,[obj2]
00401054 call Person::Person (0401000h)
00401000 push ebp
00401001 mov ebp,esp
00401003 sub esp,44h
00401006 push ebx
00401007 push esi
00401008 push edi
00401009 mov dword ptr [this],ecx
0040100C mov eax,dword ptr [this]
0040100F mov dword ptr [eax+4],1
00401016 mov eax,dword ptr [this]
00401019 pop edi
0040101A pop esi
0040101B pop ebx
0040101C mov esp,ebp
0040101E pop ebp
0040101F ret
*/
return 0;
}
继承构造
#include <iostream>
#include <Windows.h>
class Base
{
public:
int m_A;
Base()
{
std::cout << "Base" << std::endl;
m_A = 1;
}
~Base()
{
std::cout << "~Base" << std::endl;
m_A = 0;
}
};
class Son1 : public Base
{
public:
int m_A;
Son1()
{
std::cout << "Son1" << std::endl;
m_A = 2;
}
~Son1()
{
std::cout << "~Son1" << std::endl;
m_A = 0;
}
};
int main()
{
Son1 objSon;
/*
00401079 lea ecx,[objSon]
0040107C call Son1::Son1 (0401020h)
00401029 mov dword ptr [this],ecx
0040102C mov ecx,dword ptr [this]
0040102F call Base::Base (0401000h)
00401009 mov dword ptr [this],ecx
0040100C mov eax,dword ptr [this]
0040100F mov dword ptr [eax],1
00401015 mov eax,dword ptr [this]
00401034 mov eax,dword ptr [this]
00401037 mov dword ptr [eax+4],2
0040103E mov eax,dword ptr [this]
004017B8 lea ecx,[objSon]
004017BB call Son1::~Son1 (04015E0h)
004015E9 mov dword ptr [this],ecx
004015EC mov eax,dword ptr [this]
004015EF mov dword ptr [eax+4],0
004015F6 mov ecx,dword ptr [this]
004015F9 call Base::~Base (04015C0h)
004015C9 mov dword ptr [this],ecx
004015CC mov eax,dword ptr [this]
004015CF mov dword ptr [eax],0
*/
return 0;
}
继承(单)
#include <iostream>
#include <Windows.h>
class Base
{
public:
int m_A;
Base()
{
std::cout << "Base" << std::endl;
m_A = 1;
}
};
class Son1 : public Base
{
public:
int m_B;
Son1()
{
std::cout << "Son1" << std::endl;
m_B = 2;
}
};
class Son2 : public Son1
{
public:
int m_C;
Son2()
{
std::cout << "Son2" << std::endl;
m_C = 3;
}
};
int main()
{
std::cout << sizeof(Base) << std::endl;
std::cout << sizeof(Son1) << std::endl;
std::cout << sizeof(Son2) << std::endl;
Son2 objSon;
objSon.m_A = 1;
objSon.m_B = 2;
objSon.m_C = 3;
/*
LEA ECX, OBJADDR
CALL SON2::SON2
MOV ECX, THIS
CALL SON1::SON1
MOV ECX, THIS
CALL BASE::BASE
MOV M_A, 1
MOV M_B, 2
MOV M_C, 3
*/
return 0;
}
继承(多)
#include <iostream>
#include <Windows.h>
class Base1
{
public:
int m_A;
Base1()
{
m_A = 1;
}
};
class Base2
{
public:
int m_B;
Base2()
{
m_B = 2;
}
};
class Son1 : public Base1, public Base2
{
public:
int m_C;
Son1()
{
m_C = 3;
}
};
int main()
{
std::cout << sizeof(Base1) << std::endl;
std::cout << sizeof(Base2) << std::endl;
std::cout << sizeof(Son1) << std::endl;
Son1 obj;
obj.m_A = 1;
obj.m_B = 2;
obj.m_C = 3;
/*
LEA ECX, OBJADDR
CALL SON1::SON1
MOV ECX, THIS
CALL BASE1::BASE1
MOV M_A, 1
MOV ECX, THIS
CALL BASE2::BASE2
MOV M_B, 2
MOV M_C, 3
*/
return 0;
}
继承(菱)
#include <iostream>
#include <Windows.h>
class Base
{
public:
int m_A;
Base()
{
m_A = 1;
}
};
class Dev1 : public Base
{
public:
int m_B;
Dev1()
{
m_B = 2;
}
};
class Dev2 : public Base
{
public:
int m_C;
Dev2()
{
m_C = 3;
}
};
class Son : public Dev1, public Dev2
{
public:
int m_D;
Son()
{
m_D = 4;
}
};
int main()
{
/*
基类
/ \
派生 派生
\ /
子类
*/
std::cout << sizeof(Base) << std::endl;
std::cout << sizeof(Dev1) << std::endl;
std::cout << sizeof(Dev2) << std::endl;
std::cout << sizeof(Son) << std::endl;
Son obj;
/*
0x0019FED0 01 00 00 00 ....
0x0019FED4 02 00 00 00 ....
0x0019FED8 01 00 00 00 ....
0x0019FEDC 03 00 00 00 ....
0x0019FEE0 04 00 00 00 ....
*/
/*
LEA ECX, OBJADDR
CALL SON::SON
MOV ECX, THIS
CALL DEV1::DEV1
MOV ECX, THIS
CALL BASE::BASE
MOV M_A, 1
MOV M_B, 1
MOV ECX, THIS
CALL DEV2::DEV2
MOV ECX, THIS
CALL BASE::BASE
MOV M_A, 1
MOV M_c, 1
MOV M_D, 4
*/
return 0;
}
多态(单)
#include <iostream>
#include <Windows.h>
class Animal
{
public:
int m_A;
public:
virtual void MakeSound()
{
std::cout << "Animal::MakeSound" << std::endl;
}
};
class Dog : public Animal
{
public:
int m_B;
public:
void MakeSound() override
{
std::cout << "Dog::MakeSound" << std::endl;
}
};
class Cat : public Animal
{
public:
int m_C;
public:
void MakeSound() override
{
std::cout << "Cat::MakeSound" << std::endl;
}
};
int main()
{
Animal anm;
Dog dog;
Cat cat;
/*
004017D9 lea ecx,[anm]
004017DC call Animal::Animal (04013E0h)
004017E1 lea ecx,[dog]
004017E4 call Dog::Dog (0401430h)
004017E9 lea ecx,[cat]
004017EC call Cat::Cat (0401400h)
004013E9 mov dword ptr [this],ecx
004013EC mov eax,dword ptr [this]
004013EF mov dword ptr [eax],offset Animal::`vftable' (0404154h)
004013F5 mov eax,dword ptr [this]
多态机制
__vfptr -> 虚函数指针
mov dword ptr [eax],offset Animal::`vftable' (0404154h)
__vftablr -> 虚函数表
0x00404154 80 16 40 00 €.@.
0x00404158 41 6e 69 6d Anim
0x0040415C 61 6c 3a 3a al::
0x00404160 4d 61 6b 65 Make
__vfaddr -> 虚函数地址
0x00401680 Animal::MakeSound(void):
*/
std::cout << sizeof(Animal) << std::endl;
std::cout << sizeof(Dog) << std::endl;
std::cout << sizeof(Cat) << std::endl;
int* vfptr = (int*)(*(int*)(&anm));
int vfaddr1 = vfptr[0];
int vfaddr2 = vfptr[1];
Animal* parPtr;
parPtr = &dog;
parPtr->MakeSound();
/*
0040186A lea eax,[dog]
0040186D mov dword ptr [parPtr],eax
00401870 mov eax,dword ptr [parPtr] dog.Addr
00401873 mov edx,dword ptr [eax] dog.vtftable
00401875 mov ecx,dword ptr [parPtr] dog.Addr
00401878 mov eax,dword ptr [edx] dog.vtfaddr
0040187A call eax
*/
parPtr = &cat;
parPtr->MakeSound();
return 0;
}
多态(多)
#include <iostream>
#include <Windows.h>
class Base1
{
public:
int m_A = 1;
public:
virtual void Fun1() {}
};
class Base2
{
public:
int m_B = 2;
public:
virtual void Fun2() {}
};
class Son : public Base1, public Base2
{
public:
int m_C = 3;
public:
virtual void Fun1() {}
virtual void Fun2() {}
};
int main()
{
std::cout << sizeof(Base1) << std::endl;
std::cout << sizeof(Base2) << std::endl;
std::cout << sizeof(Son) << std::endl;
Son obj;
/*
Son
+0 vfptr1
+4 vfptr2
+8 var
004011BA lea ecx,[obj]
004011BD call Son::Son (0401080h)
00401089 mov dword ptr [this],ecx
0040109F mov eax,dword ptr [this]
004010A2 mov dword ptr [eax],offset Son::`vftable' (040312Ch)
004010A8 mov eax,dword ptr [this]
004010AB mov dword ptr [eax+4],offset Son::`vftable' (0403134h)
0x0019FEDC 2c 31 40 00 ,1@. Base1.vftable
0x0040312C e0 10 40 00 reverse.exe!Son::Fun1(void)
0x0019FEE0 34 31 40 00 41@. Base2.vftable
0x00403134 20 11 40 00 reverse.exe!Son::Fun2(void)
*/
int vfaddr1 = *(PDWORD)((PUCHAR)(&obj) + 0);
int vfaddr2 = *(PDWORD)((PUCHAR)(&obj) + 4);
/*
父类1 -> 虚函数指针 -> 成员变量
0x0019FED0 2c 31 40 00 ,1@.
0x0019FED4 01 00 00 00 ....
父类2 -> 虚函数指针 -> 成员变量
0x0019FED8 34 31 40 00 41@.
0x0019FEDC 02 00 00 00 ....
子类
0x0019FEE0 03 00 00 00 ....
*/
return 0;
}
虚表(单)
#include <iostream>
#include <Windows.h>
class Person1
{
public:
int m_A;
public:
const int m_B = 1;
public:
void Fun1() {}
public:
static int ver;
static int Fun2() {}
};
int Person1::ver = 0;
class Base1
{
public:
virtual void Fun1() {}
public:
int m_A = 1;
protected:
int m_B = 2;
private:
int m_C = 3;
};
class Base2 : public Base1
{
public:
virtual void Fun2() {}
public:
int m_A = 5;
};
class Son1 : public Base2
{
/*
public:
int m_A;
protected:
int m_B;
private:
int m_C;
*/
public:
virtual void Fun1() override {}
virtual void Fun2() override {}
public:
int m_D = 4;
};
int main()
{
// 对象模型
{
// 数据类型 标识符 = 初始值;
Person1 obj = {};
std::cout << sizeof(obj) << std::endl;
// 空的类对象占用内存空间1字节,需要为对应的变量分配内存空间
obj.Fun1();
/*
004010A9 lea ecx,[ebp-1]
004010AC call Person1::Fun (0401040h)
*/
// 类对象中的普通成员函数不会占用内存空间
obj.ver = 1;
// 类对象中的静态成员不会占用内存空间
}
{
std::cout << sizeof(Base1) << std::endl;
std::cout << sizeof(Base2) << std::endl;
std::cout << sizeof(Son1) << std::endl;
Base1* p1;
Base2* p2;
Son1 obj;
p1 = &obj;
p2 = &obj;
p1->Fun1();
p2->Fun2();
/*
0040125B lea eax,[ebp-28h]
0040125E mov dword ptr [ebp-0Ch],eax
00401261 lea eax,[ebp-28h]
00401264 mov dword ptr [ebp-10h],eax
00401267 mov eax,dword ptr [ebp-0Ch]
0040126A mov edx,dword ptr [eax]
0040126C mov ecx,dword ptr [ebp-0Ch]
0040126F mov eax,dword ptr [edx]
00401271 call eax
00401273 mov eax,dword ptr [ebp-10h]
00401276 mov edx,dword ptr [eax]
00401278 mov ecx,dword ptr [ebp-10h]
0040127B mov eax,dword ptr [edx+4]
0040127E call eax
*/
}
return 0;
}
虚表(多)
#include <iostream>
#include <Windows.h>
class Base1
{
public:
int m_A;
public:
virtual void Fun1() {}
virtual void Fun2() {}
};
class Base2
{
public:
int m_B;
public:
virtual void Fun3() {}
virtual void Fun4() {}
};
class Son : public Base1, public Base2
{
public:
int m_C;
public:
virtual void Fun1() override {}
virtual void Fun2() override {}
virtual void Fun3() override {}
virtual void Fun4() override {}
};
int main()
{
// 对象模型
std::cout << sizeof(Base1) << std::endl;
std::cout << sizeof(Base2) << std::endl;
std::cout << sizeof(Son) << std::endl;
Son obj{};
/*
0x0019FED0 34 31 40 00 41@.
0x0019FED4 00 00 00 00 ....
0x0019FED8 40 31 40 00 @1@.
0x0019FEDC 00 00 00 00 ....
0x0019FEE0 00 00 00 00 ....
*/
return 0;
}
纯虚
#include <iostream>
#include <Windows.h>
class Base
{
public:
virtual void Fun() = 0;
};
class Son : public Base
{
public:
virtual void Fun() override {}
};
int main()
{
Son obj;
/*
00401099 lea ecx,[obj]
0040109C call Son::Son (0401020h)
00401029 mov dword ptr [this],ecx
0040102C mov ecx,dword ptr [this]
0040102F call Base::Base (0401000h)
00401009 mov dword ptr [this],ecx
0040100C mov eax,dword ptr [this]
0040100F mov dword ptr [eax],offset Base::`vftable' (0403104h)
00401034 mov eax,dword ptr [this]
00401037 mov dword ptr [eax],offset Son::`vftable' (040310Ch)
*/
return 0;
}