热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++反汇编继承

单继承,父类中没有虚函数单继承,父类存在虚函数,子类重写虚函数单继承,父类存在虚函数,子类不新定义虚函数单继承,父类存在虚函数,子类新定义虚函数单继承,父类不存在虚函数,子类定义虚


  1. 单继承,父类中没有虚函数

  2. 单继承,父类存在虚函数,子类重写虚函数

  3. 单继承,父类存在虚函数,子类不新定义虚函数

  4. 单继承,父类存在虚函数,子类新定义虚函数

  5. 单继承,父类不存在虚函数,子类定义虚函数

  6. 多继承,父类都有虚函数,子类有重写虚函数

  7. 多继承,父类1,父类2,其中父类1没有虚函数,父类2有虚函数,子类新定义虚函数

  8. 多继承,父类中都没有虚函数,子类新定义虚函数

  9. 菱形继承


 



  • 单继承,父类中没有虚函数

// 用于初始化列表使用的类
class CInit
{
public:
CInit(int nNumber){
m_nNumber = nNumber;
}
int m_nNumber;

    ~CInit() {
      printf("CInit析构函数调用\n");
    }

};

class CBase
{
public:
CBase()
{
printf("CBase\r\n");
}
~CBase()
{
printf("~CBase\r\n");
}
void SetNumber(int nNumber)
{
m_nBase = nNumber;
}
int GetNumber()
{
return m_nBase;
}
public:
int m_nBase;
};
class CDervie : public CBase
{
public:
void ShowNumber(int nNumber)
{
SetNumber(nNumber);
m_nDervie = nNumber + 1;
printf("%d\r\n", GetNumber());
printf("%d\r\n", m_nDervie);
}
void SetNumber(int nNumber){ // 覆盖父类成员方法
m_nBase = nNumber;
}
CDervie():m_Init(1)
{
printf("构造列表使用\r\n");
}
   ~CDervie() {

      printf("CDervie析构函数调用\r\n");
    }

public:
int m_nDervie;
int m_nBase; // 覆盖父类数据成员
CInit m_Init; // 初始化列表使用类
};

类CDervie单继承类CBase,在类CDervie中存在一个CInit类成员,

void main(int argc, char* argv[])
{
CDervie Dervie;
Dervie.SetNumber(argc);
printf("%d\r\n", Dervie.m_nBase);
printf("%d\r\n", Dervie.CBase::m_nBase);
}

内存布局

汇编

298: CDervie Dervie;
0114760D 8D 4D E0 lea ecx,[Dervie]
01147610 E8 A5 B7 FF FF call CDervie::CDervie (01142DBAh)
01147615 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
299: Dervie.SetNumber(argc);
0114761C 8B 45 08 mov eax,dword ptr [argc]
0114761F 50 push eax
01147620 8D 4D E0 lea ecx,[Dervie]
01147623 E8 66 B6 FF FF call CDervie::SetNumber (01142C8Eh)
300: printf("%d\r\n", Dervie.m_nBase);
01147628 8B 45 E8 mov eax,dword ptr [ebp-18h] //
0114762B 50 push eax
0114762C 68 68 2E 1E 01 push offset string "%d\r\n" (011E2E68h)
01147631 E8 94 9D FF FF call _printf (011413CAh)
01147636 83 C4 08 add esp,8
301: printf("%d\r\n", Dervie.CBase::m_nBase);
01147639 8B 45 E0 mov eax,dword ptr [Dervie] //
301: printf("%d\r\n", Dervie.CBase::m_nBase);
0114763C 50 push eax
0114763D 68 68 2E 1E 01 push offset string "%d\r\n" (011E2E68h)
01147642 E8 83 9D FF FF call _printf (011413CAh)
01147647 83 C4 08 add esp,8

构造函数

CDervie::CDervie (01142DBAh)

011471DF 89 4D EC mov dword ptr [this],ecx
011471E2 8B 4D EC mov ecx,dword ptr [this]
011471E5 E8 06 B3 FF FF call CBase::CBase (011424F0h) //先调用父类构造函数
011471EA C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
52: CDervie():m_Init(1)
011471F1 6A 01 push 1
011471F3 8B 4D EC mov ecx,dword ptr [this]
011471F6 83 C1 0C add ecx,0Ch //m_Init类成员在类中偏移为0xc,
011471F9 E8 55 CD FF FF call CInit::CInit (01143F53h) //再调用类成员的构造函数,
54: printf("构造列表使用\r\n");
011471FE 68 70 2E 1E 01 push offset string "\xb9\xb9\xd4\xec\xc1\xd0\xb1\xed\xca\xb9\xd3\xc3\r\n" (011E2E70h)
01147203 E8 C2 A1 FF FF call _printf (011413CAh) //最后调用自身构造函数
01147208 83 C4 04 add esp,4
55: }

析构函数

01147661 8D 4D E0 lea ecx,[Dervie]
01147664 E8 FE B4 FF FF call CDervie::~CDervie (01142B67h)//子类的析构函数
******************************************************************

CDervie::~CDervie
003F73CF 59 pop ecx
59: ~CDervie() {
003F73D0 89 4D F8 mov dword ptr [this],ecx
60: printf("CDervie析构函数调用\r\n");
003F73D3 68 6C 30 49 00 push offset string "CDervie\xce\xf6\xb9\xb9\xba\xaf\xca\xfd\xb5\xf7\xd3\xc3\r\n" (049306Ch)
003F73D8 E8 ED 9F FF FF call _printf (03F13CAh) //子类先调用自身的析构函数
003F73DD 83 C4 04 add esp,4
61: }
003F73E0 8B 4D F8 mov ecx,dword ptr [this]
003F73E3 83 C1 0C add ecx,0Ch
003F73E6 E8 B7 CC FF FF call CInit::~CInit (03F40A2h) //再调用子类 类成员的析构函数
003F73EB 8B 4D F8 mov ecx,dword ptr [this]
003F73EE E8 8E A2 FF FF call CBase::~CBase (03F1681h) //最后调用父类析构函数

析构顺序与构造顺序正好相反。

 



 



  • 单继承,父类存在虚函数,子类重写虚函数,

class CBase
{
public:
CBase()
{
printf("CBase\r\n");
}
~CBase()
{
printf("~CBase\r\n");
}
void SetNumber(int nNumber)
{
m_nBase = nNumber;
}
int GetNumber()
{
return m_nBase;
}
virtual void fun1() { //父类中定义虚函数fun1
printf("CBase fun1\n");
}
virtual void fun2() { //虚函数fun2
printf("CBase fun2\n");
}
public:
int m_nBase;
};
class CDervie : public CBase
{
public:
void ShowNumber(int nNumber)
{
SetNumber(nNumber);
m_nDervie = nNumber + 1;
printf("%d\r\n", GetNumber());
printf("%d\r\n", m_nDervie);
}
void SetNumber(int nNumber){ // 覆盖父类成员方法
m_nBase = nNumber;
}
virtual void fun1() { //子类中重写虚函数。
printf("CDervie fun1\n");
}
CDervie():m_Init(1)
{
printf("构造列表使用\r\n");
}
~CDervie() {
printf("CDervie析构函数调用\r\n");
}
public:
int m_nDervie;
int m_nBase; // 覆盖父类数据成员
CInit m_Init; // 初始化列表使用类
};

内存布局

 CDervie构造函数

CDervie::CDervie(void)
011371DF 89 4D EC mov dword ptr [this],ecx
011371E2 8B 4D EC mov ecx,dword ptr [this]
011371E5 E8 06 B3 FF FF call CBase::CBase (011324F0h) //先构造父类,因为父类中含虚函数,所以进入后会设置其自身的虚表指针,
011371EA C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
011371F1 8B 45 EC mov eax,dword ptr [this]
011371F4 C7 00 A0 2E 1D 01 mov dword ptr [eax],offset CDervie::`vftable' (011D2EA0h) //设置子类虚表指针
64: CDervie():m_Init(1)
011371FA 6A 01 push 1
011371FC 8B 4D EC mov ecx,dword ptr [this]
011371FF 83 C1 10 add ecx,10h
01137202 E8 4C CD FF FF call CInit::CInit (01133F53h) //类成员构造
66: printf("构造列表使用\r\n");
01137207 68 60 2F 1D 01 push offset string "\xb9\xb9\xd4\xec\xc1\xd0\xb1\xed\xca\xb9\xd3\xc3\r\n" (011D2F60h)
0113720C E8 B9 A1 FF FF call _printf (011313CAh) //子类自身构造
01137211 83 C4 04 add esp,4
67: }

CBase::CBase(void)

0113715F 59 pop ecx
01137160 89 4D F8 mov dword ptr [this],ecx
01137163 8B 45 F8 mov eax,dword ptr [this]
01137166 C7 00 60 2E 1D 01 mov dword ptr [eax],offset CBase::`vftable' (011D2E60h) //
23: {
24: printf("CBase\r\n");
0113716C 68 50 2E 1D 01 push offset string "CBase\r\n" (011D2E50h)
01137171 E8 54 A2 FF FF call _printf (011313CAh)
01137176 83 C4 04 add esp,4

CDervie析构函数

CDervie::~CDervie(void)
011373CF 59 pop ecx
011373D0 89 4D F8 mov dword ptr [this],ecx
011373D3 8B 45 F8 mov eax,dword ptr [this]
011373D6 C7 00 A0 2E 1D 01 mov dword ptr [eax],offset CDervie::`vftable' (011D2EA0h) //设置子类自身的虚表指针。
69: printf("CDervie析构函数调用\r\n");
011373DC 68 A8 31 1D 01 push offset string "CDervie\xce\xf6\xb9\xb9\xba\xaf\xca\xfd\xb5\xf7\xd3\xc3\r\n" (011D31A8h)
011373E1 E8 E4 9F FF FF call _printf (011313CAh) //先调用子类析构函数
011373E6 83 C4 04 add esp,4
70: }
011373E9 8B 4D F8 mov ecx,dword ptr [this]
011373EC 83 C1 10 add ecx,10h
011373EF E8 AE CC FF FF call CInit::~CInit (011340A2h) //子类 类成员
011373F4 8B 4D F8 mov ecx,dword ptr [this]
011373F7 E8 85 A2 FF FF call CBase::~CBase (01131681h) //父类,在父类中要设置自身的虚表指针。

CBase::~CBase(void)

0113737F 59 pop ecx
01137380 89 4D F8 mov dword ptr [this],ecx
01137383 8B 45 F8 mov eax,dword ptr [this]
01137386 C7 00 60 2E 1D 01 mov dword ptr [eax],offset CBase::`vftable' (011D2E60h) //父类虚表指针。
28: printf("~CBase\r\n");
0113738C 68 70 2E 1D 01 push offset string "~CBase\r\n" (011D2E70h)
01137391 E8 34 A0 FF FF call _printf (011313CAh)
01137396 83 C4 04 add esp,4

 



 



  • 单继承,父类存在虚函数,子类不定义虚函数

内存布局

 

 



 



  • 单继承,父类存在虚函数,子类新定义虚函数

此时子类新定义的虚函数,将添加到虚表中。

 

 



 



  • 单继承,父类不存在虚函数,子类定义虚函数

内存布局

  -子类虚表指针              

  -父类

  -子类自身数据成员

 



 



  • 多继承,父类都有虚函数,子类有重写虚函数

class CBase
{
public:
CBase()
{
printf("CBase\r\n");
}
~CBase()
{
printf("~CBase\r\n");
}
void SetNumber(int nNumber)
{
m_nBase = nNumber;
}
int GetNumber()
{
return m_nBase;
}
virtual void fun1() {
printf("CBase fun1\n");
}
virtual void fun2() {
printf("CBase fun2\n");
}
public:
int m_nBase;
};
class CBase1 {

public:
CBase1() {
n_base = 1;
printf("CBase1 构造函数");
}
~CBase1() {
printf("CBase1 构造函数");
}
int n_base;
virtual void fun3() {
printf("CBase1 fun3\n");
}
virtual void fun4() {
printf("CBase1 fun4\n");
}
};
class CDervie : public CBase1,public CBase
{
public:
void ShowNumber(int nNumber)
{
SetNumber(nNumber);
m_nDervie = nNumber + 1;
printf("%d\r\n", GetNumber());
printf("%d\r\n", m_nDervie);
}
void SetNumber(int nNumber){ // 覆盖父类成员方法
m_nBase = nNumber;
}
//virtual void fun1() {
// printf("CDervie fun1\n");
//}
virtual void fun3() {
printf("CDervie fun3\n");
}
CDervie():m_Init(1)
{
printf("构造列表使用\r\n");
}
~CDervie() {
printf("CDervie析构函数调用\r\n");
}
public:
int m_nDervie;
int m_nBase; // 覆盖父类数据成员
CInit m_Init; // 初始化列表使用类
};

内存布局

 CDervie::CDervie(void)构造函数

0036722F 89 4D EC mov dword ptr [this],ecx
00367232 8B 4D EC mov ecx,dword ptr [this]
00367235 E8 90 CE FF FF call CBase1::CBase1 (03640CAh) //构造子类时先按照继承顺序构造父类
85: {
0036723A C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
00367241 8B 4D EC mov ecx,dword ptr [this]
00367244 83 C1 08 add ecx,8
00367247 E8 A4 B2 FF FF call CBase::CBase (03624F0h) //继承的第二个父类
0036724C C6 45 FC 01 mov byte ptr [ebp-4],1
00367250 8B 45 EC mov eax,dword ptr [this]
00367253 C7 00 AC 31 40 00 mov dword ptr [eax],offset CDervie::`vftable' (04031ACh) //设置父类1中的虚表指针
00367259 8B 45 EC mov eax,dword ptr [this]
0036725C C7 40 08 80 2E 40 00 mov dword ptr [eax+8],offset CDervie::`vftable' (0402E80h) //设置父类2中的虚表指针
84: CDervie():m_Init(1)
00367263 6A 01 push 1
00367265 8B 4D EC mov ecx,dword ptr [this]
00367268 83 C1 18 add ecx,18h
0036726B E8 E3 CC FF FF call CInit::CInit (0363F53h)
86: printf("构造列表使用\r\n");
00367270 68 78 30 40 00 push offset string "\xb9\xb9\xd4\xec\xc1\xd0\xb1\xed\xca\xb9\xd3\xc3\r\n" (0403078h)
00367275 E8 50 A1 FF FF call _printf (03613CAh)
0036727A 83 C4 04 add esp,4
87: }

CDervie::~CDervie(void)析构函数

0036761F 59 pop ecx
00367620 89 4D F8 mov dword ptr [this],ecx
00367623 8B 45 F8 mov eax,dword ptr [this]
00367626 C7 00 AC 31 40 00 mov dword ptr [eax],offset CDervie::`vftable' (04031ACh) //析构先设置虚表指针
0036762C 8B 45 F8 mov eax,dword ptr [this]
0036762F C7 40 08 80 2E 40 00 mov dword ptr [eax+8],offset CDervie::`vftable' (0402E80h)
89: printf("CDervie析构函数调用\r\n");
00367636 68 B4 31 40 00 push offset string "CDervie\xce\xf6\xb9\xb9\xba\xaf\xca\xfd\xb5\xf7\xd3\xc3\r\n" (04031B4h)
0036763B E8 8A 9D FF FF call _printf (03613CAh)
00367640 83 C4 04 add esp,4
90: }
00367643 8B 4D F8 mov ecx,dword ptr [this]
00367646 83 C1 18 add ecx,18h
00367649 E8 54 CA FF FF call CInit::~CInit (03640A2h)
0036764E 8B 4D F8 mov ecx,dword ptr [this]
90: }
00367651 83 C1 08 add ecx,8
00367654 E8 28 A0 FF FF call CBase::~CBase (0361681h) //父类析构与声明顺序相反。
00367659 8B 4D F8 mov ecx,dword ptr [this]
0036765C E8 7D CA FF FF call CBase1::~CBase1 (03640DEh)

 



 



  • 多继承,父类1,父类2,其中父类1没有虚函数,父类2有虚函数,子类新定义虚函数

内存布局(一般情况下内存布局按照继承声明的顺序。当父类存在虚函数时,有虚表指针的父类排在前面,并且子类新声明的虚函数添加到虚表后面。)

  -父类2(有虚表)     --虚表{……(子类中如果有重写虚函数,则修改对应表项),(子类新定义的虚函数添加到后面)}

  -父类1(没虚表)

  -子类自身数据成员

 



 



  • 多继承,父类中都没有虚函数,子类新定义虚函数

内存布局

  -虚表指针

  -父类1

  -父类2

  -子类自身数据成员



 



  • 虚基类

// 虚基类分析
class CVirtualBase{
public:
virtual void Show() = 0;
};
class CVirtualChild : public CVirtualBase{
public:
virtual void Show()
{
printf("虚基类分析\r\n");
}
};

 

内存布局

CVirtualChild VirtualChild;
VirtualChild.Show();

364: CVirtualChild VirtualChild;
001DD51A 8D 4D CC lea ecx,[VirtualChild]
001DD51D E8 23 69 FF FF call CVirtualChild::CVirtualChild (01D3E45h)
365: VirtualChild.Show();
001DD522 8D 4D CC lea ecx,[VirtualChild]
001DD525 E8 3A 4A FF FF call CVirtualChild::Show (01D1F64h)

CVirtualChild::CVirtualChild(void)构造函数

001D73FF 59 pop ecx
001D7400 89 4D F8 mov dword ptr [this],ecx
001D7403 8B 4D F8 mov ecx,dword ptr [this]
001D7406 E8 A6 B8 FF FF call CVirtualBase::CVirtualBase (01D2CB1h)
001D740B 8B 45 F8 mov eax,dword ptr [this]
001D740E C7 00 F4 3E 27 00 mov dword ptr [eax],offset CVirtualChild::`vftable' (0273EF4h)
001D7414 8B 45 F8 mov eax,dword ptr [this]

CVirtualBase::CVirtualBase(void)构造

001D73AF 59 pop ecx
001D73B0 89 4D F8 mov dword ptr [this],ecx
001D73B3 8B 45 F8 mov eax,dword ptr [this]
001D73B6 C7 00 E4 3E 27 00 mov dword ptr [eax],offset CVirtualBase::`vftable' (0273EE4h)
001D73BC 8B 45 F8 mov eax,dword ptr [this]

 

 纯虚函数没有具体实现,CVirtualBase虚表中填入了__purecall函数,防止误用。

 



 



  • 菱形继承

 

 

 

class CFurniture{
public:
CFurniture(){
m_nPrice = 0;
}
virtual ~CFurniture(){ // 家具类虚析构函数
printf("virtual ~CFurniture()\r\n");
}
virtual int GetPrice(){ // 获取家具价格
return m_nPrice;
};
protected:
int m_nPrice; // 家具类成员变量
};
// 定义沙发类,继承自CFurniture,等同与类B
class CSofa : virtual public CFurniture{
public:
CSofa(){
m_nPrice = 1;
m_nColor = 2;
}
virtual ~CSofa(){ // 沙发类虚析构函数
printf("virtual ~CSofa()\r\n");
}
virtual int GetColor(){ // 获取沙发颜色
return m_nColor;
}
virtual int SitDown(){ // 沙发可以坐下休息
return printf("Sit down and rest your legs\r\n");
}
protected:
int m_nColor; // 沙发类成员变量
};
// 定义床类,继承自CFurniture,等同与类C
class CBed : virtual public CFurniture{
public:
CBed(){
m_nPrice = 3;
m_nLength = 4;
m_nWidth = 5;
}
virtual ~CBed(){ // 床类虚析构函数
printf("virtual ~CBed()\r\n");
}
virtual int GetArea(){ // 获取床面积
return m_nLength * m_nWidth;
}
virtual int Sleep(){ // 床可以用来睡觉
return printf("go to sleep\r\n");
}
protected:
int m_nLength; // 床类成员变量
int m_nWidth;
};
// 子类沙发床定义,派生自CSofa、CBed类,等同与类D
class CSofaBed : public CSofa, public CBed{
public:
CSofaBed(){
m_nHeight = 6;
}
virtual ~CSofaBed(){ // 沙发床类虚析构函数
printf("virtual ~CSofaBed()\r\n");
}
virtual int SitDown(){ // 沙发可以坐下休息
return printf("Sit down on the sofa bed\r\n");
}
virtual int Sleep(){ // 床可以用来睡觉
return printf("go to sleep on the sofa bed\r\n");
}
virtual int GetHeight(){
return m_nHeight;
}
protected:
int m_nHeight; // 沙发类成员变量
};

// 菱形结构
CSofaBed SofaBed;
CFurniture * pFurniture = &SofaBed;
CSofa * pSofa = &SofaBed;
CBed * pBed = &SofaBed;

 

内存布局

 

SofaBed对象中对应的虚表

'-__vfptr 0x00ed3eb0 {ClassRelation.exe!void(* CSofaBed::`vftable'[4])()} 

[0x00000000] 0x00e340ed {ClassRelation.exe!CSofa::GetColor(void)}

[0x00000001] 0x00e34129 {ClassRelation.exe!CSofaBed::SitDown(void)}

[0x00000002] 0x00e34138 {ClassRelation.exe!CSofaBed::GetHeight(void)} (子类中新定义的虚函数,添加到了第一个虚表中)

offset_ptr1 (指向一表,第一项为offset_ptr1到所属类虚表指针的偏移,第二项为到父类虚表指针的偏移)

0x00ED3EBC  fc ff ff ff

0x00ED3EC0  1c 00 00 00

'- __vfptr 0x00ed3e88 {ClassRelation.exe!void(* CSofaBed::`vftable'[3])()}
[0x00000000] 0x00e3411f {ClassRelation.exe!CBed::GetArea(void)} void *
[0x00000001] 0x00e3410b {ClassRelation.exe!CSofaBed::Sleep(void)} void *

0x00ED3EE8  fc ff ff ff

0x00ED3EEC  10 00 00 00

'- __vfptr 0x00ed3ed4 {ClassRelation.exe!void(* CSofaBed::`vftable'[3])()}
[0x00000000] 0x00e340e8 {ClassRelation.exe!CSofaBed::`vector deleting destructor'(unsigned int)} void *
[0x00000001] 0x00e3413d {ClassRelation.exe!CFurniture::GetPrice(void)} void *

汇编

368: // 菱形结构
369: CSofaBed SofaBed;
00E3A8CE 6A 01 push 1 //是否构造祖父类标志,
00E3A8D0 8D 4D D4 lea ecx,[SofaBed]
00E3A8D3 E8 06 98 FF FF call CSofaBed::CSofaBed (0E340DEh)
370: CFurniture * pFurniture = &SofaBed;
00E3A8D8 8D 45 D4 lea eax,[SofaBed]
00E3A8DB 85 C0 test eax,eax //检查对象是否构造成功
00E3A8DD 75 0C jne main+3Bh (0E3A8EBh)
00E3A8DF C7 85 E8 FE FF FF 00 00 00 00 mov dword ptr [ebp-118h],0
00E3A8E9 EB 10 jmp main+4Bh (0E3A8FBh)
00E3A8EB 8B 4D D8 mov ecx,dword ptr [ebp-28h] //SofaBed对象的第二项,对应CSofa类的偏移指针
00E3A8EE 8B 51 04 mov edx,dword ptr [ecx+4] //取得CSofa的父类,即CFurniture偏移量
00E3A8F1 8D 44 15 D8 lea eax,[ebp+edx-28h] //根据偏移量,得到CFurniture在内存布局中的相对位置地址
00E3A8F5 89 85 E8 FE FF FF mov dword ptr [ebp-118h],eax //局部变量转存
00E3A8FB 8B 8D E8 FE FF FF mov ecx,dword ptr [ebp-118h]
00E3A901 89 4D C8 mov dword ptr [pFurniture],ecx
371: CSofa * pSofa = &SofaBed;
00E3A904 8D 45 D4 lea eax,[SofaBed] //CSofa在对象SofaBed内存布局中排在第一项
371: CSofa * pSofa = &SofaBed;
00E3A907 89 45 BC mov dword ptr [pSofa],eax
372: CBed * pBed = &SofaBed;
00E3A90A 8D 45 D4 lea eax,[SofaBed]
00E3A90D 85 C0 test eax,eax
00E3A90F 74 0E je main+6Fh (0E3A91Fh)
00E3A911 8D 4D D4 lea ecx,[SofaBed]
00E3A914 83 C1 0C add ecx,0Ch //CBed在对象中偏移位0xc
00E3A917 89 8D E8 FE FF FF mov dword ptr [ebp-118h],ecx
00E3A91D EB 0A jmp main+79h (0E3A929h)
00E3A91F C7 85 E8 FE FF FF 00 00 00 00 mov dword ptr [ebp-118h],0
00E3A929 8B 95 E8 FE FF FF mov edx,dword ptr [ebp-118h]
00E3A92F 89 55 B0 mov dword ptr [pBed],edx
373: }

CSofaBed::CSofaBed(void)构造函数

310: CSofaBed(){
00E42CA2 C7 85 20 FF FF FF 00 00 00 00 mov dword ptr [ebp-0E0h],0 //设置构造标志
00E42CAC 83 7D 08 00 cmp dword ptr [ebp+8],0 //判断祖父类构造标志
00E42CB0 74 35 je CSofaBed::CSofaBed+87h (0E42CE7h)
00E42CB2 8B 45 EC mov eax,dword ptr [this]
00E42CB5 C7 40 04 BC 3E ED 00 mov dword ptr [eax+4],offset CSofaBed::`vbtable' (0ED3EBCh) //设置CSofa的偏移指针
00E42CBC 8B 45 EC mov eax,dword ptr [this]
00E42CBF C7 40 10 E8 3E ED 00 mov dword ptr [eax+10h],offset CSofaBed::`vbtable' (0ED3EE8h) //设置CBed的偏移指针
00E42CC6 8B 4D EC mov ecx,dword ptr [this]
00E42CC9 83 C1 20 add ecx,20h
00E42CCC E8 62 14 FF FF call CFurniture::CFurniture (0E34133h)
00E42CD1 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
00E42CD8 8B 85 20 FF FF FF mov eax,dword ptr [ebp-0E0h]
00E42CDE 83 C8 01 or eax,1 //构造标志置1
00E42CE1 89 85 20 FF FF FF mov dword ptr [ebp-0E0h],eax
00E42CE7 6A 00 push 0 //压入0作为构造标志
00E42CE9 8B 4D EC mov ecx,dword ptr [this]
00E42CEC E8 CF 13 FF FF call CSofa::CSofa (0E340C0h) //CSofa构造
00E42CF1 C7 45 FC 01 00 00 00 mov dword ptr [ebp-4],1
00E42CF8 6A 00 push 0 //压入0作为构造标志
00E42CFA 8B 4D EC mov ecx,dword ptr [this]
00E42CFD 83 C1 0C add ecx,0Ch
00E42D00 E8 D4 13 FF FF call CBed::CBed (0E340D9h) //CBed构造
00E42D05 8B 45 EC mov eax,dword ptr [this]
00E42D08 C7 00 B0 3E ED 00 mov dword ptr [eax],offset CSofaBed::`vftable' (0ED3EB0h) //设置CSofaBed对应的CSofa虚表指针
00E42D0E 8B 45 EC mov eax,dword ptr [this]
00E42D11 C7 40 0C 88 3E ED 00 mov dword ptr [eax+0Ch],offset CSofaBed::`vftable' (0ED3E88h) //设置CSofaBed对应的CBed虚表指针
00E42D18 8B 45 EC mov eax,dword ptr [this]
00E42D1B 8B 48 04 mov ecx,dword ptr [eax+4] //取CSofa的偏移指针
00E42D1E 8B 51 04 mov edx,dword ptr [ecx+4] //取偏移表的第二项,即到其父类CFurniture的偏移。
00E42D21 8B 45 EC mov eax,dword ptr [this]
00E42D24 C7 44 10 04 D4 3E ED 00 mov dword ptr [eax+edx+4],offset CSofaBed::`vftable' (0ED3ED4h) //设置CSofaBed对应的CFurniture的虚表指针
311: m_nHeight = 6;
00E42D2C 8B 45 EC mov eax,dword ptr [this]
00E42D2F C7 40 1C 06 00 00 00 mov dword ptr [eax+1Ch],6
312: }

函数

CSofa::CSofa:
00E340C0 E9 9B 31 00 00 jmp CSofa::CSofa (0E37260h)
CSofa::`vector deleting destructor':
00E340C5 E9 36 40 00 00 jmp CSofa::`scalar deleting destructor' (0E38100h)
CFurniture::`vector deleting destructor':
00E340CA E9 D1 35 00 00 jmp CFurniture::`scalar deleting destructor' (0E376A0h)
CSofa::`vbase destructor':
00E340CF E9 BC 34 00 00 jmp CSofa::`vbase destructor' (0E37590h)
CBed::`vbase destructor':
00E340D4 E9 27 34 00 00 jmp CBed::`vbase destructor' (0E37500h)
CBed::CBed:
00E340D9 E9 F2 37 00 00 jmp CBed::CBed (0E378D0h)
CSofaBed::CSofaBed:
00E340DE E9 7D EB 00 00 jmp CSofaBed::CSofaBed (0E42C60h)
CSofaBed::`vector deleting destructor':
00E340E3 E9 18 36 00 00 jmp CSofaBed::`scalar deleting destructor' (0E37700h)
CSofaBed::`vector deleting destructor':
00E340E8 E9 13 36 00 00 jmp CSofaBed::`scalar deleting destructor' (0E37700h)
CSofa::GetColor:
00E340ED E9 AE 93 00 00 jmp CSofa::GetColor (0E3D4A0h)
CSofa::`vector deleting destructor':
00E340F2 E9 09 40 00 00 jmp CSofa::`scalar deleting destructor' (0E38100h)
CFurniture::~CFurniture:
00E340F7 E9 E4 32 00 00 jmp CFurniture::~CFurniture (0E373E0h)
CFurniture::`vector deleting destructor':
00E340FC E9 9F 35 00 00 jmp CFurniture::`scalar deleting destructor' (0E376A0h)
CBed::Sleep:
00E34101 E9 3A 35 00 00 jmp CBed::Sleep (0E37640h)
CSofaBed::~CSofaBed:
00E34106 E9 85 38 00 00 jmp CSofaBed::~CSofaBed (0E37990h)
CSofaBed::Sleep:
00E3410B E9 60 36 00 00 jmp CSofaBed::Sleep (0E37770h)
CBed::`vector deleting destructor':
00E34110 E9 0B 39 00 00 jmp CBed::`scalar deleting destructor' (0E37A20h)
CSofa::SitDown:
00E34115 E9 66 32 00 00 jmp CSofa::SitDown (0E37380h)
CSofa::~CSofa:
00E3411A E9 11 33 00 00 jmp CSofa::~CSofa (0E37430h)
CBed::GetArea:
00E3411F E9 9C 36 00 00 jmp CBed::GetArea (0E377C0h)
CSofaBed::`vbase destructor':
00E34124 E9 C7 34 00 00 jmp CSofaBed::`vbase destructor' (0E375F0h)
CSofaBed::SitDown:
00E34129 E9 72 33 00 00 jmp CSofaBed::SitDown (0E374A0h)
CBed::~CBed:
00E3412E E9 DD 31 00 00 jmp CBed::~CBed (0E37310h)
CFurniture::CFurniture:
00E34133 E9 B8 30 00 00 jmp CFurniture::CFurniture (0E371F0h)
CSofaBed::GetHeight:
00E34138 E9 23 37 00 00 jmp CSofaBed::GetHeight (0E37860h)
CFurniture::GetPrice:
00E3413D E9 EE 30 00 00 jmp CFurniture::GetPrice (0E37230h)
CBed::`vector deleting destructor':
00E34142 E9 D9 38 00 00 jmp CBed::`scalar deleting destructor' (0E37A20h)

推荐阅读
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
author-avatar
_红裙子_Supreme
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有