程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++構造函數與析構函數

C++構造函數與析構函數

編輯:C++入門知識

 

//a.h代碼:
#pragma once
#include <iostream>
using namespace std;
void test();
#include "a.h"
//a.cpp代碼:
class MyTest
{
public:
    MyTest(){
        cout << "MyTest()" << endl;
    }
    ~MyTest(){
        cout << "~MyTest()" << endl;
    }
};
void test()
{
    MyTest test;
}
//main.cpp
#include <iostream>
#include "a.h"
int main() 
{
    test();
    int a=5;
    int b=6;
    return 0;
}
int main()
{
004114C0  push        ebp  
004114C1  mov         ebp,esp
004114C3  sub         esp,0D8h
004114C9  push        ebx  
004114CA  push        esi  
004114CB  push        edi  
004114CC  lea         edi,[ebp-0D8h]
004114D2  mov         ecx,36h
004114D7  mov         eax,0CCCCCCCCh
004114DC  rep stos    dword ptr es:[edi]
    callmyfunc();
004114DE  call        callmyfunc (41125Dh)
    int a=5;
004114E3  mov         dword ptr [a],5
    int b=6;
004114EA  mov         dword ptr [b],6
    return 0;
004114F1  xor         eax,eax
}

0041125D  jmp         callmyfunc (411520h)

void callmyfunc()
{
00411520  push        ebp  
00411521  mov         ebp,esp
00411523  sub         esp,0CCh
00411529  push        ebx  
0041152A  push        esi  
0041152B  push        edi  
0041152C  lea         edi,[ebp-0CCh]
00411532  mov         ecx,33h
00411537  mov         eax,0CCCCCCCCh
0041153C  rep stos    dword ptr es:[edi]
    MyTest mytestclass;
0041153E  lea         ecx,[mytestclass]
00411541  call        MyTest::MyTest (4111C7h)
}
00411546  lea         ecx,[mytestclass]
00411549  call        MyTest::~MyTest (41102Dh)
0041154E  push        edx  
0041154F  mov         ecx,ebp
00411551  push        eax  
00411552  lea         edx,[ (411574h)]
00411558  call        @ILT+170(@_RTC_CheckStackVars@8) (4110AFh)
0041155D  pop         eax  
0041155E  pop         edx  
0041155F  pop         edi  
00411560  pop         esi  
00411561  pop         ebx  
00411562  add         esp,0CCh
00411568  cmp         ebp,esp
0041156A  call        @ILT+415(__RTC_CheckEsp) (4111A4h)
0041156F  mov         esp,ebp
00411571  pop         ebp  
00411572  ret
 

call 指令
CPU執行call指令,進行兩步操作:
(1)將當前的 IP 或 CS和IP 壓入棧中;
(2)轉移。

call 指令在實現轉移之前, 要將返回地址存入堆棧的, 以便子程可以通過 ret 指令返回到 CALL 指令下面的指令接著運行;
jmp 就沒用這些事兒, 直接過去就過去了, 以後的執行流程全由那裡的說了算. 當然了, 一些特殊的執行流程控制技巧除外.



大概的意思,匯編我也不怎麼懂.
004114DE  call        callmyfunc (41125Dh)
0041125D  jmp         callmyfunc (411520h)
然後直接jmp 到callmyfunc函數的地址.
callmyfunc函數結束的後面,加入了調用析構的代碼如下:
00411546  lea         ecx,[mytestclass]
00411549  call        MyTest::~MyTest (41102Dh)

現在大概知道C++析構的原理了,編譯器對調用函數做了個子過程包裝,
然後加入析構調用代碼.最後返回.

這樣看來,如果函數中產生異常,可能會導致析構函數不能正確的調用,從而導致內存洩漏.

根據分析,繼續測試.

\

\


摘自 天下

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved