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
0
投稿
猜你喜欢
- 一、概述1.1 什么是Java工厂模式Java工厂模式是一种创建对象的设计模式,它提供了一种方法,通过该方法可以在不暴露对象创建逻辑的情况下
- C#一些延时函数sleep延时方法System.Threading.Thread.Sleep(1000); //毫秒实现的是非独占性延时函数
- 本文实例讲述了Android实现捕获TextView超链接的方法。分享给大家供大家参考,具体如下:这里分享一篇捕获TextView超链接的文
- 本文实例为大家分享了Unity Shader实现描边OutLine效果的具体代码,供大家参考,具体内容如下Shader实现描边流程大致为:对
- 一. 为什么需要比较对象上一节介绍了优先级队列,在优先级队列中插入的元素必须能比较大小,如果不能比较大小,如插入两个学生类型的元素,会报Cl
- 这两天看阿里的JAVA开发手册,到多线程的时候说永远不要用 new Thread()这种方式来使用多线程。确实是这样的,我一直在用线程池,到
- EasyTouch摇杆插件使用,先给大家展示下效果图:Demo展示双指缩放在电脑端无法掩饰,竖屏将就看看吧;插件名叫EasyTouch,有需
- Android EasyPlayer声音自动停止、恢复,一键静音等功能我们在开发播放器时,可能会需要静音或者降低音量的功能。比如说某款音乐播
- 详解android 通过uri获取bitmap图片并压缩很多人在调用图库选择图片时会在onActivityResult中用Media.get
- SpringTask是Spring自带的功能。实现起来比较简单。使用SpringTask实现定时任务有两种方式:1.注解方式基于注解@Sch
- 本文实例为大家分享了swing登录注册界面展示的具体代码,供大家参考,具体内容如下开发环境:Eclipse Neon.3 Release (
- 如题,有时候看见一个布局写上几百行看上去会非常吃力麻烦,这时候抽取控件样式很有必要了, Android Studio提供了抽取Style样式
- 前言环境: flutter sdk v1.7.8+hotfix.3@stable对应 flutter engine: 54ad777f这里关
- 本文实例讲述了基于JavaMail API收发邮件的方法。分享给大家供大家参考。具体如下:1.JavaMail API按其功能划分通常可分为
- 先来看看下面List<T>泛型集合的排序例子:using System;using System.Collections.Gen
- JdbcTemplate概述它是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了
- 问题描述Spring Cache提供的@Cacheable注解不支持配置过期时间,还有缓存的自动刷新。我们可以通过配置CacheManneg
- 代码入下:import java.io.*; public class Practice { publ
- 有看过我之前发表过的C#相关文章分享和阅读过我代码的朋友们可能会在我的代码里面经常看到各种各样的λ表达式动态拼接,C#
- 一、概述1、事务ACID特性事务将一系列的工作视为一个工作单元,它具有 ACID 特性:A:Atomicity 不可分性 也就是说