C++編譯器會對沒有構造函數的類生成默認構造函數嗎?(有必要的時候才生成,要看情況。有反匯編驗證)


之前在上C++的課的時候,印象中有那么一句話:
如果一個類沒有任何構造函數,那么編譯器會生成一個默認的構造函數

今天在看《深度探索C++對象模型》的第二章:“構造函數語意學”的時候發現之前聽到的說法是錯誤的。

比如說如下代碼:

class A {
public:
int a;
};

int main(void) {
A a;
a.a = 4;
A a2;
a2.a=5;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
按照之前的說法,類A沒有任何構造函數,編譯器會自動生成一個默認的構造函數,但事實是並不會。把上面的代碼反匯編后可以看到結果:

main:
push rbp
mov rbp, rsp #int main(void)
mov DWORD PTR [rbp-4], 4 #a.a = 4;
mov DWORD PTR [rbp-8], 5 #a2.a=5;
mov eax, 0 #return 0;
pop rbp
ret
1
2
3
4
5
6
7
8
我們可以發現這個類的對象被直接拿來用了,沒有調用任何構造函數,也沒有任何的初始化。

根據《深度探索C++對象模型》書上的說法,編譯器只在一定需要默認構造函數時,才會創建默認構造函數,比如說:

class A {
public:
A() {a = 0; }
int a;
};
class B : public A {
A _tmp;
};
int main(void) {
B b;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
在類B對象初始化時,類B對象中存在一個需要默認構造函數進行初始化的類A對象,那么類B對象必須要有默認構造函數,因此編譯器在迫不得已的情況下創建了類B對象的默認構造函數。
反匯編可以看到類B的默認構造函數:

A::A() [base object constructor]:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], 0
nop
pop rbp
ret
B::B() [base object constructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call A::A() [base object constructor]
mov rax, QWORD PTR [rbp-8]
add rax, 4
mov rdi, rax
call A::A() [complete object constructor]
nop
leave
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-8]
mov rdi, rax
call B::B() [complete object constructor]
mov eax, 0
leave
ret

————————————————
版權聲明:本文為CSDN博主「zhangpeterx」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zhangpeterx/article/details/102762410


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM