1:c++類裡面無論如何都會有乙個拷貝建構函式(隱含的或者顯示的),是這樣的嗎?
2:大學課本裡是這樣寫的若乙個類不帶有拷貝建構函式,則系統為該類隱含定義乙個拷貝建構函式(出自《第245頁)真是這樣的嗎?
當追根究底其實都是錯的,拷貝建構函式未必必須有,想想如果乙個類一點都不複雜,編譯器還要定義乙個拷貝建構函式,進行一次函式的呼叫操作,對程式執行的效率將是多麼大的傷害呀?
c++標準是這樣寫的:
預設拷貝建構函式是在必要的時候由編譯器進行合成的,這裡是在必要的時候而不是一定,不是嗎:)
證明:程式一:
[cpp] view plaincopyprint?
class a
; int main()
class a
;int main()
按照書中寫的,在a b=a時會發生拷貝建構函式的呼叫操作,是這樣的吧:),讓我們進入彙編**看看真的是這樣的嗎,除錯進入彙編**執行
[cpp] view plaincopyprint?
11: a a;
12: a b=a;
00401048 mov eax,dword ptr [ebp-8]
0040104b mov dword ptr [ebp-10h],eax
0040104e mov ecx,dword ptr [ebp-4]
00401051 mov dword ptr [ebp-0ch],ecx
11: a a;
12: a b=a;
00401048 mov eax,dword ptr [ebp-8]
0040104b mov dword ptr [ebp-10h],eax
0040104e mov ecx,dword ptr [ebp-4]
00401051 mov dword ptr [ebp-0ch],ecx你看到有a:a( a &a)這樣的函式呼叫操作嗎?我是沒有看到:),有的只是通過暫存器以及堆疊操作來進行的複製操作(即按位元位進行的複製操作),拷貝建構函式是不會產生的。
程式二:
class a
; int main()
class a
;int main()
同樣,按照書中寫的,在a b=a時會發生拷貝建構函式的呼叫操作,是這樣的吧:),讓我們進入彙編**看看真的是這樣的嗎,除錯進入彙編**執行
11: a a;
0040117d lea ecx,[ebp-20h]
00401180 call @ilt+55(a::a) (0040103c)
00401185 mov dword ptr [ebp-4],0
12: a b=a;
0040118c lea eax,[ebp-20h]
0040118f push eax
00401190 lea ecx,[ebp-34h]
00401193 call @ilt+140(a::a) (00401091)
13: return 0;
11: a a;
0040117d lea ecx,[ebp-20h]
00401180 call @ilt+55(a::a) (0040103c)
00401185 mov dword ptr [ebp-4],0
12: a b=a;
0040118c lea eax,[ebp-20h]
0040118f push eax
00401190 lea ecx,[ebp-34h]
00401193 call @ilt+140(a::a) (00401091)
13: return 0;你看到有a:a( a &a)這樣的函式呼叫操作嗎?看到了吧,拷貝建構函式產生了,這是為什麼呢。
a::a:
004012a0 push ebp
004012a1 mov ebp,esp
004012a3 sub esp,44h
004012a6 push ebx
004012a7 push esi
004012a8 push edi
004012a9 push ecx
004012aa lea edi,[ebp-44h]
004012ad mov ecx,11h
004012b2 mov eax,0cccccccch
004012b7 rep stos dword ptr [edi]
004012b9 pop ecx
004012ba mov dword ptr [ebp-4],ecx
004012bd mov eax,dword ptr [ebp-4]
004012c0 mov ecx,dword ptr [ebp+8]
004012c3 mov edx,dword ptr [ecx]
004012c5 mov dword ptr [eax],edx
004012c7 mov eax,dword ptr [ebp+8]
004012ca add eax,4
004012cd push eax
004012ce mov ecx,dword ptr [ebp-4]
004012d1 add ecx,4
004012d4 call @ilt+150(std::basic_string,std::allocator >::basic_str
004012d9 mov eax,dword ptr [ebp-4]
004012dc pop edi
004012dd pop esi
004012de pop ebx
004012df add esp,44h
004012e2 cmp ebp,esp
a::a:
004012a0 push ebp
004012a1 mov ebp,esp
004012a3 sub esp,44h
004012a6 push ebx
004012a7 push esi
004012a8 push edi
004012a9 push ecx
004012aa lea edi,[ebp-44h]
004012ad mov ecx,11h
004012b2 mov eax,0cccccccch
004012b7 rep stos dword ptr [edi]
004012b9 pop ecx
004012ba mov dword ptr [ebp-4],ecx
004012bd mov eax,dword ptr [ebp-4]
004012c0 mov ecx,dword ptr [ebp+8]
004012c3 mov edx,dword ptr [ecx]
004012c5 mov dword ptr [eax],edx
004012c7 mov eax,dword ptr [ebp+8]
004012ca add eax,4
004012cd push eax
004012ce mov ecx,dword ptr [ebp-4]
004012d1 add ecx,4
004012d4 call @ilt+150(std::basic_string,std::allocator >::basic_str
004012d9 mov eax,dword ptr [ebp-4]
004012dc pop edi
004012dd pop esi
004012de pop ebx
004012df add esp,44h
004012e2 cmp ebp,esp
看到了沒,紅色的,這是因為成員類物件含有拷貝建構函式,所以編譯器要合成乙個拷貝建構函式用以呼叫成員類物件的拷貝建構函式,對類物件的資料成員進行複製操作
其實上面的程式一建構函式與析構函式均不會合成,可以看一下這篇部落格c++類一定有建構函式嗎
在以下四種情況會產生預設拷貝建構函式
1:類的成員類物件有拷貝建構函式
2:類繼承的基類含有拷貝建構函式
3:類含有虛函式
4:類繼承於虛基類
C 類一定有建構函式嗎
1 任何類如果沒有定義預設建構函式,就會合成出來?2 合成出來的預設建構函式會明確設定類內每乙個成員的值?3 如何去證明呢?如果你對1 2回答的都是不是,請跳過閱讀,以免浪費你的時間 對於問題1與2其實答案都是未必,c 標準是這樣寫的預設建構函式是由編譯器在需要的時候將其合成出來,這裡強調的是需要,...
C 類(拷貝建構函式)(二)
拷貝建構函式是一種特殊的建構函式,它在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件。拷貝建構函式通常用於 如果在類中沒有定義拷貝建構函式,編譯器會自行定義乙個。如果類帶有指標變數,並有動態記憶體分配,則它必須有乙個拷貝建構函式。拷貝建構函式的最常見形式如下 classname con...
C (一) 建構函式與拷貝建構函式
2.拷貝建構函式 類通過乙個或幾個特殊的成員函式來控制其物件的初始化過程,這些函式叫做建構函式。建構函式的任務是初始化類物件的資料成員。tip 建構函式不能宣告為const的。形式1 person 不帶任何引數,合成的預設建構函式就是該形式 合成預設建構函式初始化規則 1 如果存在類內的初始值,用它...