分享

C++类一定有拷贝构造函数吗 | 学步园

 牛人的尾巴 2017-01-08

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

2017年01月06日 ? 编程语言 ? 共 1868字 ? 字号 ? 评论关闭

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:类继承于虚基类

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多