解析c++中參數(shù)對象與局部對象的析構(gòu)順序的詳解
下面是c++的源碼:
class X {
public:
int i;
int j;
~X() {}
};
void f(X x) {
X x1;
x.i = 1;
x.j = 2;
}
int main() {
f(X());
}
下面是main函數(shù)的匯編碼:
_main PROC
; 15 : int main() {
push ebp
mov ebp, esp
sub esp, 8;為臨時(shí)對象預(yù)留8byte空間,由于沒有顯示定義構(gòu)造函數(shù),
;而且這種情況下編譯器提供無用的默認(rèn)構(gòu)造函數(shù),因此看不到構(gòu)造函數(shù)的調(diào)用
; 16 : f(X());
mov eax, DWORD PTR $T2560[ebp+4];將偏移臨時(shí)變量的首地址4byte處內(nèi)存中內(nèi)容給eax,即將臨時(shí)變量的成員變量j值給eax
push eax;將eax壓棧
mov ecx, DWORD PTR $T2560[ebp];將臨時(shí)變量首地址中的內(nèi)容給ecx,即將臨時(shí)變量中的成員變量i值給ecx
push ecx;將ecx壓棧
;上面四句創(chuàng)建了臨時(shí)變量的一份拷貝,作為參數(shù)調(diào)用f
call ?f@@YAXVX@@@Z ; 調(diào)用函數(shù)f
add esp, 8;將棧頂指針下移8byte,釋放為參數(shù)對象的提供的棧空間
lea ecx, DWORD PTR $T2560[ebp];將臨時(shí)對象的首地址給ecx
call ??1X@@QAE@XZ ; 為臨時(shí)對象調(diào)用析構(gòu)函數(shù)
; 17 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
從上面可以看出,產(chǎn)生的臨時(shí)對象在函數(shù)調(diào)用完成退出后才調(diào)用析構(gòu)函數(shù)。
下面是f函數(shù)的匯編碼:
?f@@YAXVX@@@Z PROC ; f
; 9 : void f(X x) {
push ebp
mov ebp, esp
sub esp, 8;為局部對象x1預(yù)留8byte的空間
; 10 : X x1;
; 11 : x.i = 1;
mov DWORD PTR _x$[ebp], 1;把1寫給參數(shù)對象首地址處,即把1寫入?yún)?shù)對象的成員變量i
; 12 : x.j = 2;
mov DWORD PTR _x$[ebp+4], 2;把2寫入偏移參數(shù)對象首地址4byte處的內(nèi)存,即把2寫入?yún)?shù)對象的成員變量j
; 13 :
; 14 : }
lea ecx, DWORD PTR _x1$[ebp];將局部變量x1的首地址給ecx
call ??1X@@QAE@XZ ; 為x1調(diào)用析構(gòu)函數(shù)
lea ecx, DWORD PTR _x$[ebp];將參數(shù)對象的首地址給ecx
call ??1X@@QAE@XZ ; 為參數(shù)對象調(diào)用析構(gòu)函數(shù)
mov esp, ebp
pop ebp
ret 0
?f@@YAXVX@@@Z ENDP ; f
; Function compile flags: /Odtp
_TEXT ENDS
; COMDAT ??1X@@QAE@XZ
_TEXT SEGMENT
_this$ = -4 ; size = 4
??1X@@QAE@XZ PROC ; X::~X, COMDAT
; _this$ = ecx
; 6 : ~X() {}
push ebp
mov ebp, esp
push ecx
mov DWORD PTR _this$[ebp], ecx
mov esp, ebp
pop ebp
ret 0
??1X@@QAE@XZ ENDP
從上面的代碼可以看出,參數(shù)對象和局部對象都是在函數(shù)退出之前調(diào)用析構(gòu)函數(shù)。并且參數(shù)對象在局部對象調(diào)用析構(gòu)函數(shù)之后再調(diào)用自己的析構(gòu)函數(shù)。
相關(guān)文章
C語言實(shí)現(xiàn)魔方陣算法(幻方陣 奇魔方 單偶魔方實(shí)現(xiàn))
魔方陣是指由1,2,3……n2填充的,每一行、每一列、對角線之和均相等的方陣,階數(shù)n = 3,4,5…。魔方陣也稱為幻方陣,看下面的實(shí)現(xiàn)方法吧2013-11-11深入探索C++ string的底層實(shí)現(xiàn)
C語言中的字符串是以字符數(shù)組的形式存儲(chǔ)的,每個(gè)字符占用一個(gè)字節(jié)的內(nèi)存空間,本文我們將和大家一起深入探討一下string的底層實(shí)現(xiàn),感興趣的小伙伴快來和小編一起吧2023-08-08C++驗(yàn)證LeetCode包圍區(qū)域的DFS方法
這篇文章主要介紹了C++驗(yàn)證LeetCode包圍區(qū)域的DFS方法,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語言調(diào)用攝像頭實(shí)現(xiàn)生成yuv未壓縮圖片
這篇文章主要為大家詳細(xì)介紹了C語言如何調(diào)用攝像頭實(shí)現(xiàn)生成yuv未壓縮圖片,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以參考一下2023-11-11利用Qt+opencv實(shí)現(xiàn)視頻分解為圖片
這篇文章主要為大家詳細(xì)介紹了如何利用Qt和opencv實(shí)現(xiàn)視頻分解為圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12