1:C++类里面无论如何都会有一个拷贝构造函数(隐含的或者显示的),是这样的吗? 2:大学课本里是这样写的若一个类不带有拷贝构造函数,则系统为该类隐含定义一个拷贝构造函数(出自<<C++语言基础教程>>第245页)真是这样的吗? 当追根究底其实都是错的,拷贝构造函数未必必须有,想想如果一个类一点都不复杂,编译器还要定义一个拷贝构造函数,进行一次函数的调用操作,对程序运行的效率将是多么大的伤害呀?
C++标准是这样写的: 默认拷贝构造函数是在必要的时候由编译器进行合成的,这里是在必要的时候而不是一定,不是吗 证明: 程序一: class A { private: int a; char *str; }; int main() { A a; A b=a; return 0; } 按照书中写的,在A b=a时会发生拷贝构造函数的调用操作,是这样的吧:),让我们进入汇编代码看看真的是这样的吗,调试进入汇编代码运行 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; } 同样,按照书中写的,在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;
你看到有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<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:类继承于虚基类 |
|