C++类一定有拷贝构造函数吗 (一)

2014-11-24 00:04:27 · 作者: · 浏览: 11

1:C++类里面无论如何都会有一个拷贝构造函数(隐含的或者显示的),是这样的吗

2:大学课本里是这样写的若一个类不带有拷贝构造函数,则系统为该类隐含定义一个拷贝构造函数(出自<>第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)这样的函数调用操作吗?看到了吧,拷贝构造函数产生了,这是为什么呢。

 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
004012D