1:C++类里面无论如何都会有一个拷贝构造函数(隐含的或者显示的),是这样的吗
2:大学课本里是这样写的若一个类不带有拷贝构造函数,则系统为该类隐含定义一个拷贝构造函数(出自<
当追根究底其实都是错的,拷贝构造函数未必必须有,想想如果一个类一点都不复杂,编译器还要定义一个拷贝构造函数,进行一次函数的调用操作,对程序运行的效率将是多么大的伤害呀?
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