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

C++類一定有拷貝構造函數嗎

編輯:C++入門知識

1:C++類裡面無論如何都會有一個拷貝構造函數(隱含的或者顯示的),是這樣的嗎?

2:大學課本裡是這樣寫的若一個類不帶有拷貝構造函數,則系統為該類隱含定義一個拷貝構造函數(出自<<C++語言基礎教程>>第245頁)真是這樣的嗎?

當追根究底其實都是錯的,拷貝構造函數未必必須有,想想如果一個類一點都不復雜,編譯器還要定義一個拷貝構造函數,進行一次函數的調用操作,對程序運行的效率將是多麼大的傷害呀?

C++標准是這樣寫的:

默認拷貝構造函數是在必要的時候由編譯器進行合成的,這裡是在必要的時候而不是一定,不是嗎:)

證明:

程序一:

[cpp] view plaincopyprint?
class A 

private: 
    int a; 
    char *str; 
}; 
int main() 

    A a; 
    A b=a; 
    return 0; 

class A
{
private:
 int a;
 char *str;
};
int main()
{
 A a;
 A b=a;
 return 0;
}按照書中寫的,在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 
{ 
private: 
    int a; 
    string str; 
}; 
int main() 
{ 
    A a; 
    A b=a; 
    return 0; 
} 

class A
{
private:
 int a;
 string str;
};
int main()
{
 A a;
 A b=a;
 return 0;

}同樣,按照書中寫的,在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)這樣的函數調用操作嗎?看到了吧,拷貝構造函數產生了,這是為什麼呢。

 <SPAN style="FONT-SIZE: 18px">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 
<SPAN style="COLOR: #ff0000">004012D4   call        @ILT+150(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_str 
</SPAN>004012D9   mov         eax,dword ptr [ebp-4] 
004012DC   pop         edi 
004012DD   pop         esi 
004012DE   pop         ebx 
004012DF   add         esp,44h 
004012E2   cmp         ebp,esp 
</SPAN> 

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<char,std::char_traits<char>,std::allocator<char> >::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:類繼承於虛基類

 

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