C++中的拷贝构造详解
作者:悲伤土豆拌饭 发布时间:2021-12-04 03:56:27
标签:C++,拷贝,构造
拷贝构造函数
同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完美可行的,这个拷贝过程只需要拷贝数据成员,而函数成员是公用的(只有一份代码);在建立对象时可用同一类的另一个对象来初始化该对象的存储空间,这时所用的构造函数称为拷贝构造函数
例如:
class Object
{
int value;
public:
Object(int x = 0) :value(x) {}
~Object() {}
Object(Object& obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
};
int main()
{
Object obja(10);
Object objb(obja);//一个对象初始化另一个对象空间,调用拷贝构造
}
当一个对象去初始化另一个对象空间,调用拷贝构造;若类中没有写拷贝构造,如同构造函数与析构函数一样,系统会生成一个缺省的拷贝构造函数
OBject(Object& obj)
{}
拷贝构造中的引用
如果我们在写的拷贝构造不加引用,这样会引起死递归
//Object(Object& obj):value(obj.value)
Object(Object obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
为什么拷贝构造函数必须采用引用传参,否则会引发无穷递归呢?
这个问题其实很简单,再复制对象时要分为两个步骤:
第一步:开辟一个临时空间;
第二步:由于临时空间是需要构造的,重新调用拷贝构造函数(无穷递归形成…)
同时我们可以在拷贝构造参数前加上一个引用,来限制可能会出现的问题
//Object(Object& obj):value(obj.value)
Object(const Object& obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
//这里的const修饰,令我们不能修改被拷贝对象
什么情况会使用拷贝构造
拷贝构造不止在使用一个对象去构造另一个对象时调用,在下面这些情况也会调用:
class Object{int value;public:Object(){cout << "Object::Object" << this << endl;}Object(int x = 0) :value(x){cout << "Object::Object" << this << endl;}~Object(){cout << "Objecet::~Object" << this << endl;}Object(Object& obj) :value(obj.value){cout << "Copy Create" << this << endl;}void SetValue(int x) { value = x; }int GetValue() const { return value; }};Object fun(Object obj){int val = obj.GetValue();Object obja(val);return obja;}int main(){Object objx(0);Object objy(0);objy = fun(objx);return 0;}class Object
{
int value;
public:
Object()
{
cout << "Object::Object" << this << endl;
}
Object(int x = 0) :value(x)
{
cout << "Object::Object" << this << endl;
}
~Object()
{
cout << "Objecet::~Object" << this << endl;
}
Object(Object& obj) :value(obj.value)
{
cout << "Copy Create" << this << endl;
}
void SetValue(int x) { value = x; }
int GetValue() const { return value; }
};
Object fun(Object obj)
{
int val = obj.GetValue();
Object obja(val);
return obja;
}
int main()
{
Object objx(0);
Object objy(0);
objy = fun(objx);
return 0;
}
在上面这一段代码中,我们总共创建了几个对象呢,我们来看一下
首先①②属于对象的构造,调用构造函数;程序运行到objy = fun(objx);进入到fun函数,这是构造临时对象obj③属于拷贝构造;随后④构造对象obja;最后⑤这里也属于拷贝构造也需要创建一个临时对象(将亡值)
并且我们无法将fun函数中obja对象之间return传回给objy,因为在函数结束时obja会析构失效,所以这里会创建一个新的临时对象
来源:https://blog.csdn.net/XXXTENTAC1ON/article/details/122484133


猜你喜欢
- 一、安装本地Maven选择你需要的maven版本下载:官网下载传送门我使用的是3.6.1版本:maven-3.6.1-bin.zip&nbs
- 一、简介应用程序配置文件(App.config)是标准的 XML 文件,XML 标记和属性是区分大小写的。它是可以按需要更改的,开发人员可以
- Java-关键字:final1 .final可以用来修饰的结构:类、方法、变量2.final 用来修饰一个类:此类不能被其他类所继承比如:S
- 一、前言在SpringBoot工程(注意不是SpringCloud)下使OpenFeign的大坑。为什么不用SpringCloud中的Fei
- Spring概述Spring就是为解决企业应用开发的复杂性而创建的,做为开源中间件,它使用基本的JavaBean来完成以前只可能有EJB(J
- 一、前言让我们先理一下springfox与swagger的关系。swagger是一个流行的API开发框架,这个框架以“开放API声明”(Op
- 本文实例讲述了C#开发的人脸左右相似度计算软件。分享给大家供大家参考。具体分析如下:模仿湖南卫视快乐大本营中所使用的一款人脸左右对称相似度计
- 日期格式处理在控制器中使用对象接收数据前端:<form action="test/add" method=&quo
- 本文实例讲述了Android编程之绘图canvas基本用法。分享给大家供大家参考,具体如下:MainActivity的代码如下:packag
- 1.在外部开启activity时需要新开一个task,从service里开启activity时出现了这个异常。W/System.err: a
- 先上ListView滑动改变标题栏背景渐变效果图,透明转变成不透明效果:图1:图2:图3:图4:我用的是小米Note手机,状态栏高度是55p
- 说明:此头像类似微信群组头像,整个头像由组内前N位人员的头像组合而成,可用网络或本地图片进行组合,最终显示为一个头像整体,看效果图:一、自定
- BigDecimal 和 0 比较大小调用BigDecimal中的compareTo方法, 如:int i = bigDecimal.com
- 一、Thread 类了解如何使用Thread 类实现多线程之后,继续学习Thread 类实现多线程之后的相关功能及方法。1、操作线程名称的方
- @RequestBody不能class类型匹配在首次第一次尝试使用@RequestBody注解开始加载字符串使用post提交(貌似只能pos
- 业务场景通常微服务对于用户认证信息解析有两种方案在 gateway 就解析用户的 token 然后路由的时候把 userId 等相关信息添加
- 1、什么是FeignFeign 是 Spring Cloud Netflix 组件中的一个轻量级 RESTful 的 HTTP 服务客户端,
- ProgressBar有2个子控件:SeekBar 拖动条控件RatingBar 星级评分控
- 本文实例讲述了Java常用HASH算法。分享给大家供大家参考,具体如下:/*** Hash算法大全<br>* 推荐使用FNV1算
- 本文实例讲述了Android编程防止进程被第三方软件杀死的方法。分享给大家供大家参考,具体如下:项目测试的时候发现,按home键回到桌面,再