C/C++基础 -- 复制构造函数和深浅复制

本博文由 西北工业大学MOOC 总结而来,以备以后回顾。(侵删)

1、复制构造函数

1.1、什么是复制构造函数

  复制构造函数又称为拷贝构造函数,它是一种特殊的构造函数。它的作用是用一个已经生成的对象来初始化另一个同类的对象。
  对于变量,我们可以直接通过赋值的形式来用一个变量初始化另一个变量,如:

int a=10; int b=a;

  对于对象,我们也希望使用和变量一样方便的方法实现初始化,这时我们就需要复制构造函数。

class Point;
Point pt1(10,20);//构造函数初始化对象pt1
Point pt2 = pt1;//用pt1初始化pt2时,需要复制构造函数

1.2、复制构造函数的定义

  复制构造函数的一般形式为:
在这里插入图片描述
例:
在这里插入图片描述
  复制构造函数有且只有一个本类类型对象的引用形参,通常使用const限定。因为复制构造函数只是复制对象,没有必要改变传递来的对象的的值。
  复制构造函数的功能是利用一个已知的对象来初始化一个被创建的同类的对象
  用复制构造函数初始化另一对象的形式为:

class Point;
Point pt1(10,20);//构造函数初始化对象pt1
Point pt2(pt1)//定义对象pt2并复制pt1的值

  赋值和复制的区别:
  赋值是对一个已经定义的对象进行赋值,而复制是建立一个新的对象并与一个已有的对象完全相同。

1.3、合成复制构造函数

  每个类必须有一个复制构造函数。如果没有定义复制构造函数,编译器就会自动合成一个,称为合成复制构造函数(synthesized copy constructor)。
  合成构造函数的操作是:对成员逐个进行初始化,将新对象初始化为原对象的副本。
  合成复制构造函数初始化有以下规则:

  1. 编译器将现有对象的每个非静态成员依次复制到正在创建的对象中。
  2. 内置类型(int,double等)成员直接复制其值。
  3. 类类型成员使用该类的复制构造函数进行复制。
  4. 如果一个类具有数组成员,则合成复制构造函数将复制数组的每一个元素到新对象中。

1.4、复制构造函数的使用

  以下三种情况会使用复制构造函数:
一、 用一个对象显式或是隐式的初始化另一个对象
  C++支持两种初始化形式:复制初始化和直接初始化。如下所示:

class Point;
Point pt1(10,20);//构造函数初始化对象pt1
Point pt2 = pt1; //复制初始化
Point pt3(pt1);	 //直接初始化

  复制初始化和直接初始化是有区别的。复制初始化会调用复制构造函数,直接初始化会调用与实参匹配的构造函数。

二、函数的参数按值传递对象或函数返回对象时
  当函数形参为对象类型,而非指针和引用类型,函数调用按值传递对象,则编译器会先调用复制构造函数复制产生实参的一个副本传递到函数中。
  而返回一个类类型对象时,也会调用复制构造函数产生一个副本作为return语句的值。

三、根据元素初始化式列表初始化数组元素时
  当没有为类类型数组元素提供初始化式,则将用默认构造函数初始化每个元素。而当我们使用括号的形式对数组每个元素初始化时,就会调用复制构造函数。

  总而言之,正是有了复制构造函数,函数才可以传递对象和返回对象,对象数组才能用初值列表的形式初始化。

2、深复制和浅复制

一、若复制对象但未复制资源内容,称为浅复制
在这里插入图片描述
  如图所示:如果对象 a 中有一个指针成员 p ,它指向一段存储空间。而使用对象 a 初始化对象 b 时,该指针的值也赋给了对象 b 的指针成员 p ,这样就会有两个指针指向同一段存储空间。这种只复制指针成员的值,而不复制指针所指地址内容的复制,就是浅复制。
  但是当我们撤销对象 a 时,a 的指针成员 p 会清除相应的存储空间的内容,此时对象 b 中指针成员 p 就成了迷途指针。我们再撤销对象 b 时,就会出现问题,因为同一段存储空间不能释放两次。

二、如果一个拥有资源(如用 new 得到的动态内存)的类发生复制的时候,若对象数据和资源内容一起复制,称为深复制
在这里插入图片描述
  深复制再利用对象 a 初始化 对象 b 时,为对象 b 的指针成员 p 申请一个和对象 a 的指针成员同样大小的存储空间,然后将对象 a 所指的内容复制到对象 b 中去。这种既复制指针成员的值,又复制指针所指地址内容的复制,就是深复制。
  深复制就可以解决浅复制对一段存储空间释放两次的问题。

  值得注意的是,利用系统默认的复制构造函数(即合成构造函数),所执行的都是浅复制。所以自己定义复制构造函数,在自定义复制构造函数中为相应变量申请动态内存,来实现深复制
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值