C++拷贝函数详解

如果感觉有用的话点个赞吧朋友!

如果感觉有用的话点个赞吧朋友!

如果感觉有用的话点个赞吧朋友!

六大默认构造函数:

拷贝构造:

注意事项:

拷贝构造特征:

注意思考:


六大默认构造函数:


初始化和清理:构造函数、析构函数
拷贝复制:拷贝构造、复制重载
取地址重载:对普通对象和const对象取地址

拷贝构造:


使用同类型对象再构造一个相同的对象,说白了就是拷贝对象
格式:
函数名和类名一致,参数为该类对象,而且必须使用引用,否则会被编译器认为是无限递归
然后再将引用对象的值传给新的要拷贝过去的对象的值

注意事项:

类对象传值:因为是值传参,所以本质上就是拷贝一份该类对象
而C++规定,自定义类型的传参都会调用拷贝构造函数
而使用引用传参就不用调用拷贝构造
而是直接传引用
那么,第一,为什么C++要有一个拷贝构造呢?
为了方便拷贝自定义类型对象
第二,既然有了拷贝构造,为什么又要用引用传参呢?
或者说,如果拷贝构造使用传值传参会发生什么?
首先回答拷贝使用传值传参的问题:
会形成一个死循环,无线套娃递归
为什么?
试想:对象B要拷贝对象A:classname B(A);
因为而C++规定,自定义类型的传参都会调用拷贝构造函数
所以,A就会作为B拷贝构造的参数,去调用B的拷贝构造函数
但是,A作为参数,也是要去调用A自己的拷贝构造的!
于是A去调用自己的拷贝构造
但是,A自己的拷贝构造也是要有一个参数的
而这个参数又要去调用参数对应的拷贝构造
...
总之就是,传类对象的参数,要调用拷贝构造
拷贝构造又要传参,传参又要调用拷贝对象
如此反复,无限递归
所以,基本无解
因为拷贝构造都是一直在参数哪里打转
根本没有进入函数内部
用返回值根本做不到

所以,为了解决这个问题,所以最好的方案是引用
避免了参数调用拷贝构造

一般建议在引用前面加一个const,保护,避免修改

拷贝构造特征:


1、拷贝构造是构造函数之一,即重载
2、拷贝构造的参数只有一个,而且必须是类类型对象的引用,因为使用传值传参的方式会引发无限递归,直接报错
3、构造函数属于默认构造函数之一,如果我们没有显式定义,编译器会自动生成一个;
而默认生成的拷贝构造函数中的自定义对象拷贝,会按照内存存储的字节序完成拷贝,什么意思?就是转化成为一个字节一个字节的拷贝过去,这种拷贝方式叫做浅拷贝,或者值拷贝

注意思考:

注意:依旧只有自定义类型才对去调用它的拷贝构造
同时,因为拷贝构造也是默认构造函数之一,属于构造函数的重载
所以,当我们显式写了一个默认拷贝函数,它也是属于默认构造函数
因此,编译器就不会再自动生成默认构造函数
但是,默认构造函数又要求不能有参数,所以,报错
那怎么办呢?
可以使用defualt关键字
强制生成一个默认构造函数


那么,有一个问题:既然编译器会自动生成一个默认拷贝函数来对自定义类型进行拷贝
我们还有必要再多余去写一个吗?
似乎没有必要?
也不是
而是默认生成的拷贝函数在一些场景下是控制不住的
例如说一些类的内部有typedef的指针
那么,默认拷贝的拷贝没有问题
例如说,对象1拷贝给对象2
会将指针也同样的拷贝过去
到这里,似乎没有什么问题,对吧?
真的吗?
好,那当对象销毁的时候呢?
注意!注意!注意!
两个对象的指针是一模一样的,因为是拷贝过去的,也就是说地址一样,指向的是同一个空间
好,当对象2的生命周期结束的时候,就会自动调用析构函数free指针2指向的空间
真正的问题来了老弟!
那么当对象1的生命周期结束的时候呢?
是不是也要调用它自己的析构函数进行资源清理呢?
所以,也要对其指针指向的空间进行free
可是!!!
这个空间还在吗?????
不在了老弟!
空间已经不在了!!!(你挑的嘛!偶像!!!)
所以,就会出现野指针的问题,报错
也就是说,同一块空间被释放两次


那么,要怎么解决这个问题呢?
要解决问题,首先要搞清楚问题的根源是什么
上述问题的根源是因为浅拷贝的问题
就是只是把指针的的值给拷贝过去从而导致后面的问题
所以,只要我们拷贝指针的时候,不是拷贝指针
而是开辟出一份和指针指向的空间一样大的新空间
然后再memcpy
是不是就可以了?
各自的对象的指针指向各自的空间,有各自的地址,
是的,就是这样,而这样的场景是非常多的
这就需要深拷贝
因此,编译器自动生成的默认拷贝无法控制
所以,还得我们自己写


因此,一个类的拷贝构造是否需要我们自己写
取决于什么?
取决于是否有自定义类型
要注意:自定义类型的最底层都是内置类型,所以一般不需要些
除非有typedef

如果感觉有用的话点个赞吧朋友!


 

  • 48
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十5画生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值