C++的構造函數一直比較神秘,今天我們通過匯編的角度來揭秘一下,它的本質是什么。與常規函數有什么不同。從以下這段代碼說起:
class Person
{
public:Person(int age) { _age = age; }void printAge(){ printf("age = %d\r\n",_age); }
private:int _age;
};int main()
{Person tom(20);return 1;
}
如上所示,定義了一個Person類,以及聲明了一個構造函數(帶一個int型變量)。在main函數中聲明了一個tom的對象。我們查看上面代碼對應的匯編:
Person::Person(int) [base object constructor]:push rbpmov rbp, rspmov QWORD PTR [rbp-8], rdimov DWORD PTR [rbp-12], esimov rax, QWORD PTR [rbp-8]mov edx, DWORD PTR [rbp-12]mov DWORD PTR [rax], edxnoppop rbpret
main:push rbpmov rbp, rspsub rsp, 16lea rax, [rbp-4]mov esi, 20mov rdi, raxcall Person::Person(int) [complete object constructor]mov eax, 1leaveret
重點關注main函數的匯編,通過指令“call ? ?Person::Person(int) [complete object constructor]”,我們知道是在調用Person類的構造函數。我們再注意一下這條指令:“mov ? ? esi, 20”,即將20寫入esi這個寄存器中,根據之前的文章:從匯編的角度揭開C++ this指針的神秘面紗,我們知道這是在準備Person構造函數的形參,但是跟據函數傳參約定:
esi(即RSI的低32位),傳遞的是第二個參數,RDI傳遞的是第一個參數。上面匯編代碼中,Person類的構造函數明明只有一個形參,為什么需要傳遞兩個實參呢?答案是Person類的構造函數還有一個隱含的參數,根據之前文章從匯編的角度揭開C++ this指針的神秘面紗,這個參數就是this指針!從而我們可以得出一個結論:類的構造函數與普通函數并本質區別,只不過編譯器會'偷偷地'添加一個this指針作為第一個參數。
<構造函數揭秘繼續...>