[Disclaimer: All Rights Reserved. You are welcome to reprint it. Do not use it for commercial purposes. Contact Email: feixiaoxing @ 163.com]
Inheritance is a basic attribute of a class, but how is the function initialized during the class inheritance process? How can we analyze the structure? Let's take a look at the following code?
class employee{public:employee() { printf("employee()!\n");}~employee() { printf("~employee()!\n");}};class manager : public employee{public:manager() { printf("manager()!\n");}~manager() { printf("~maneger()!\n");}};
Seeing the code above, I believe everyone understands that we have defined such a class. The base class is empoyee, and the inheritance class is Manager. We can see that manager is a special kind of employee. How can we arrange functions during memory construction and analysis?
74: manager m;00401268 lea ecx,[ebp-4]0040126B call @ILT+60(manager::manager) (00401041)75: }00401270 lea ecx,[ebp-4]00401273 call @ILT+0(manager::~manager) (00401005)00401278 pop edi00401279 pop esi0040127A pop ebx0040127B add esp,44h0040127E cmp ebp,esp00401280 call __chkesp (00408760)00401285 mov esp,ebp00401287 pop ebp
We found that the manager structure and analysis structure are also simple. A constructor is constructed when a variable appears. When will the structure be analyzed? The function is analyzed at the end of the process. Next, we can further discuss how the structure and structure of the Manager are actually implemented?
65: class manager : public employee66: {67: public:68: manager() { printf("manager()!\n");}004012A0 push ebp004012A1 mov ebp,esp004012A3 sub esp,44h004012A6 push ebx004012A7 push esi004012A8 push edi004012A9 push ecx004012AA lea edi,[ebp-44h]004012AD mov ecx,11h004012B2 mov eax,0CCCCCCCCh004012B7 rep stos dword ptr [edi]004012B9 pop ecx004012BA mov dword ptr [ebp-4],ecx004012BD mov ecx,dword ptr [ebp-4]004012C0 call @ILT+40(employee::employee) (0040102d)004012C5 push offset string "manager()!\n" (00431020)004012CA call printf (004086e0)004012CF add esp,4004012D2 mov eax,dword ptr [ebp-4]004012D5 pop edi004012D6 pop esi004012D7 pop ebx004012D8 add esp,44h004012DB cmp ebp,esp004012DD call __chkesp (00408760)004012E2 mov esp,ebp004012E4 pop ebp004012E5 ret
We found that the default constructor of employee is added to the Manager constructor. What about the Destructor?
69: ~manager() { printf("~maneger()!\n");}00401350 push ebp00401351 mov ebp,esp00401353 sub esp,44h00401356 push ebx00401357 push esi00401358 push edi00401359 push ecx0040135A lea edi,[ebp-44h]0040135D mov ecx,11h00401362 mov eax,0CCCCCCCCh00401367 rep stos dword ptr [edi]00401369 pop ecx0040136A mov dword ptr [ebp-4],ecx0040136D push offset string "~maneger()!\n" (00431040)00401372 call printf (004086e0)00401377 add esp,40040137A mov ecx,dword ptr [ebp-4]0040137D call @ILT+5(employee::~employee) (0040100a)00401382 pop edi00401383 pop esi00401384 pop ebx00401385 add esp,44h00401388 cmp ebp,esp0040138A call __chkesp (00408760)0040138F mov esp,ebp00401391 pop ebp00401392 ret
We found that when the manager is constructed, the employee is constructed first, and then the manager is printed. When the structure is analyzed, the manager first analyzes itself and then calls the destructor of the employee, the assembly code above demonstrates everything.
[Notice: The following describes virtual functions of the class]