子类构造函数先调用父类。子类保留父类一块空间。
以一个例子分析:
class A { public: A() { } ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) { } ~B() { cout<<"~B"<<endl; } private: A _a; }; int main(void) { A a; //很简单,定义a的时候调用了一次构造函数 B b(a); }
下面是反汇编代码
1: #include <iostream> 2: using namespace std; 3: class A 4: { 5: public: 6: A() 00401240 push ebp 00401241 mov ebp,esp 00401243 sub esp,44h 00401246 push ebx 00401247 push esi 00401248 push edi 00401249 push ecx 0040124A lea edi,[ebp-44h] 0040124D mov ecx,11h 00401252 mov eax,0CCCCCCCCh 00401257 rep stos dword ptr [edi] 00401259 pop ecx 0040125A mov dword ptr [ebp-4],ecx 7: { 8: cout << "A construct" << endl; 0040125D push offset @ILT+35(std::endl) (00401028) 00401262 push offset string "A construct" (0043201c) 00401267 push offset std::cout (00439528) 0040126C call @ILT+180(std::operator<<) (004010b9) 00401271 add esp,8 00401274 mov ecx,eax 00401276 call @ILT+120(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040107d) 9: } 0040127B mov eax,dword ptr [ebp-4] 0040127E pop edi 0040127F pop esi 00401280 pop ebx 00401281 add esp,44h 00401284 cmp ebp,esp 00401286 call __chkesp (004096e0) 0040128B mov esp,ebp 0040128D pop ebp 0040128E ret 10: A operator=(const A &a) 11: { 12: cout << "operator = " << endl; 13: return a; 14: } 15: A(const A& a) 复制构造函数 004013B0 push ebp 004013B1 mov ebp,esp 004013B3 sub esp,44h 004013B6 push ebx 004013B7 push esi 004013B8 push edi 004013B9 push ecx 004013BA lea edi,[ebp-44h] 004013BD mov ecx,11h 004013C2 mov eax,0CCCCCCCCh 004013C7 rep stos dword ptr [edi] 004013C9 pop ecx 004013CA mov dword ptr [ebp-4],ecx 16: { 17: cout << "const A&" << endl; 004013CD push offset @ILT+35(std::endl) (00401028) 004013D2 push offset string "const A&" (00432030) 004013D7 push offset std::cout (00439528) 004013DC call @ILT+180(std::operator<<) (004010b9) 004013E1 add esp,8 004013E4 mov ecx,eax 004013E6 call @ILT+120(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040107d) 18: } 004013EB mov eax,dword ptr [ebp-4] 004013EE pop edi 004013EF pop esi 004013F0 pop ebx 004013F1 add esp,44h 004013F4 cmp ebp,esp 004013F6 call __chkesp (004096e0) 004013FB mov esp,ebp 004013FD pop ebp 004013FE ret 4 19: ~A() 20: { 004012B0 push ebp 004012B1 mov ebp,esp 004012B3 sub esp,44h 004012B6 push ebx 004012B7 push esi 004012B8 push edi 004012B9 push ecx 004012BA lea edi,[ebp-44h] 004012BD mov ecx,11h 004012C2 mov eax,0CCCCCCCCh 004012C7 rep stos dword ptr [edi] 004012C9 pop ecx 004012CA mov dword ptr [ebp-4],ecx 21: cout<<"~A"<<endl; 004012CD push offset @ILT+35(std::endl) (00401028) 004012D2 push offset string "~A" (0043202c) 004012D7 push offset std::cout (00439528) 004012DC call @ILT+180(std::operator<<) (004010b9) 004012E1 add esp,8 004012E4 mov ecx,eax 004012E6 call @ILT+120(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040107d) 22: } 004012EB pop edi 004012EC pop esi 004012ED pop ebx 004012EE add esp,44h 004012F1 cmp ebp,esp 004012F3 call __chkesp (004096e0) 004012F8 mov esp,ebp 004012FA pop ebp 004012FB ret 23: }; 24: 25: class B:public A 26: { 27: public: 28: B(A &a):_a(a) 29: { 00401310 push ebp 00401311 mov ebp,esp 00401313 push 0FFh 00401315 push offset [email protected]@[email protected]@@@Z (0041fd79) 0040131A mov eax,fs:[00000000] 00401320 push eax 00401321 mov dword ptr fs:[0],esp 00401328 sub esp,44h 0040132B push ebx 0040132C push esi 0040132D push edi 0040132E push ecx 0040132F lea edi,[ebp-50h] 00401332 mov ecx,11h 00401337 mov eax,0CCCCCCCCh 0040133C rep stos dword ptr [edi] 0040133E pop ecx 0040133F mov dword ptr [ebp-10h],ecx 00401342 mov ecx,dword ptr [ebp-10h] 00401345 call @ILT+80(A::A) (00401055) 普通构造函数 B类有A类对象。 0040134A mov dword ptr [ebp-4],0 00401351 mov eax,dword ptr [ebp+8] 00401354 push eax 00401355 mov ecx,dword ptr [ebp-10h] 00401358 call @ILT+165(A::A) (004010aa) 复制构造函数 30: // _a = a; 31: } 0040135D mov dword ptr [ebp-4],0FFFFFFFFh 00401364 mov eax,dword ptr [ebp-10h] 00401367 mov ecx,dword ptr [ebp-0Ch] 0040136A mov dword ptr fs:[0],ecx 00401371 pop edi 00401372 pop esi 00401373 pop ebx 00401374 add esp,50h 00401377 cmp ebp,esp 00401379 call __chkesp (004096e0) 0040137E mov esp,ebp 00401380 pop ebp 00401381 ret 4 32: ~B() 33: { 00401420 push ebp 00401421 mov ebp,esp 00401423 push 0FFh 00401425 push offset [email protected]@[email protected] (0041fda2) 0040142A mov eax,fs:[00000000] 00401430 push eax 00401431 mov dword ptr fs:[0],esp 00401438 sub esp,44h 0040143B push ebx 0040143C push esi 0040143D push edi 0040143E push ecx 0040143F lea edi,[ebp-50h] 00401442 mov ecx,11h 00401447 mov eax,0CCCCCCCCh 0040144C rep stos dword ptr [edi] 0040144E pop ecx 0040144F mov dword ptr [ebp-10h],ecx 00401452 mov dword ptr [ebp-4],1 34: cout<<"~B"<<endl; 00401459 push offset @ILT+35(std::endl) (00401028) 0040145E push offset string "~B" (0043203c) 00401463 push offset std::cout (00439528) 00401468 call @ILT+180(std::operator<<) (004010b9) 0040146D add esp,8 00401470 mov ecx,eax 00401472 call @ILT+120(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040107d) 35: } 00401477 mov byte ptr [ebp-4],0 0040147B mov ecx,dword ptr [ebp-10h] 0040147E call @ILT+110(A::~A) (00401073) 00401483 mov dword ptr [ebp-4],0FFFFFFFFh 0040148A mov ecx,dword ptr [ebp-10h] 0040148D call @ILT+110(A::~A) (00401073) 00401492 mov ecx,dword ptr [ebp-0Ch] 00401495 mov dword ptr fs:[0],ecx 0040149C pop edi 0040149D pop esi 0040149E pop ebx 0040149F add esp,50h 004014A2 cmp ebp,esp 004014A4 call __chkesp (004096e0) 004014A9 mov esp,ebp 004014AB pop ebp 004014AC ret 36: private: 37: A _a; 38: }; 39: 40: int main(void) 41: { 00401190 push ebp 00401191 mov ebp,esp 00401193 push 0FFh 00401195 push offset __ehhandler$_main (0041fd59) 0040119A mov eax,fs:[00000000] 004011A0 push eax 004011A1 mov dword ptr fs:[0],esp 004011A8 sub esp,4Ch 004011AB push ebx 004011AC push esi 004011AD push edi 004011AE lea edi,[ebp-58h] 004011B1 mov ecx,13h 004011B6 mov eax,0CCCCCCCCh 004011BB rep stos dword ptr [edi] 42: A a; //很简单,定义a的时候调用了一次构造函数 004011BD lea ecx,[ebp-10h] 004011C0 call @ILT+80(A::A) (00401055) 004011C5 mov dword ptr [ebp-4],0 43: B b(a); 004011CC lea eax,[ebp-10h] 004011CF push eax 004011D0 lea ecx,[ebp-14h] 004011D3 call @ILT+155(B::B) (004010a0) 44: return 0; 004011D8 mov dword ptr [ebp-18h],0 004011DF lea ecx,[ebp-14h] 004011E2 call @ILT+130(B::~B) (00401087) 004011E7 mov dword ptr [ebp-4],0FFFFFFFFh 004011EE lea ecx,[ebp-10h] 004011F1 call @ILT+110(A::~A) (00401073) 004011F6 mov eax,dword ptr [ebp-18h] 45: } 004011F9 mov ecx,dword ptr [ebp-0Ch] 004011FC mov dword ptr fs:[0],ecx 00401203 pop edi 00401204 pop esi 00401205 pop ebx 00401206 add esp,58h 00401209 cmp ebp,esp 0040120B call __chkesp (004096e0) 00401210 mov esp,ebp 00401212 pop ebp 00401213 ret @ILT+145(_main): 00401096 jmp main (00401190) @ILT+155([email protected]@[email protected]@@@Z): 004010A0 jmp B::B (00401310) @ILT+165([email protected]@[email protected]@@Z): 004010AA jmp A::A (004013b0) 复制构造函数 @ILT+110([email protected]@[email protected]): 00401073 jmp A::~A (004012b0) @ILT+130([email protected]@[email protected]): 00401087 jmp B::~B (00401420) @ILT+80([email protected]@[email protected]): 00401055 jmp A::A (00401240) 普通构造函数
时间: 2024-09-28 13:05:33