【C++学习笔记】拷贝构造函数以及深拷贝和浅拷贝

概念

拷贝构造函数是一种特殊的构造函数,其形参是本类对象的引用。其作用是使用一个已经存在的对象去初始化另一个同类的对象。

说明

1.在定义时通过等于号复制对象时,系统会自动调用拷贝构造函数。(注意,不是在任何时候等于号赋值都可以调用拷贝构造函数)
2.拷贝构造函数与原来构造函数实现了函数的重载。
(拷贝构造函数是构造函数的一个重载)

使用情景

  1. 一个对象作为函数参数,以值传递的方式传入函数体;
  2. 一个对象作为函数返回值,以值传递的方式从函数返回;
    3)一个对象用于给另外一个对象进行初始化(常称为赋值初始化);
    来自百度百科

特点

  • 拷贝构造函数的本质还是构造函数,所以其函数名和类名相同也不能有返回值类型。
  • 该函数只能有一个参数,并且是同类对象的引用。
  • 每个类都必须由一个拷贝构造函数。程序员可以定义特定的拷贝构造函数,以实现同类对象间的传递。如果没有定义,系统会自动补齐一个缺省的拷贝构造函数。(每一个类都必须有构造函数、拷贝构造函数、一定要有析构函数。这三个函数就像是人体中细胞必须要有细胞体、细胞复制、细胞凋亡一样,是最基础的功能)

拷贝构造函数的定

class 类名
{
public:
	类名(形参);
	类名(类名&对象名);//拷贝构造函数
	};
	类名::类名(类名&对象名)
	{}

//实例
class Human
{
public:
	Human();
	Human(Human&);
	};
	Human::Human(Human&){
		cout<<"This human is copied!"<

拷贝构造函数的使用细节

下面这个例子说明多种情形下拷贝构造函数的使用,大家可以先计算一下这里调用了几次拷贝构造函数。

#include 
using namespace std;
#define Max(a,b)((a)>(b):(a):(b)cout<

}
}
int main() {
Human pp(1);
cout<<"-------"< Human dd=pp;
cout<<"--------"< Human son(dd);
cout<<"--------"< son =pp;
cout<<"--------"< son = marrage(pp,dd);
cout<<"--------"< Who_marraage_money(dd,pp);
cout<<"--------"< Who_control_everything(pp,dd);
cout<<"--------"< return 0;
}

结果为:

-------
This human is copied!
--------
This human is copied!
--------
--------
This human is copied!
This human is copied!
--------
This human is copied!
This human is copied!
This human is copied!
--------
--------

接下来我们来分析一下为什么会这样。

int main() {
        Human  pp(1);//这里括号中值为1,只是调用了普通构造函数,符合函数重载的特点
        cout<<"-------"<

浅拷贝和深拷贝

  • 浅拷贝就是由缺省的构造函数所实现的数据成员逐一赋值,若类中含有指针类型的数据,则会产生错误。(如上例中dd=pp;的操作)
  • 因此,为了解决浅拷贝中出现的错误,必须显式地定义一个自己的拷贝构造函数,使之不但能拷贝数据成员,而且为对象1和对象2分配各自的空间,这就是所谓的深拷贝。
    -为什么是浅拷贝?因为在拷贝构造函数中吸收的参数是该类的引用,系统是不给它分配对象的,所以无论怎么操作,最后生成的son或者dd都是和pp用同一个空间而已,并不会生成新的内存空间。(注意不是类的地址相同,而是数据成员用了同一个地址)

也就是说,在浅拷贝中,拷贝的变量和被拷贝的变量用的是同一块数据空间,当出现涉及内存的操作时,很容易出现问题。
【C++学习笔记】拷贝构造函数以及深拷贝和浅拷贝_第1张图片

深拷贝:通过在拷贝构造函数中定义新的内存来实现深入的拷贝效果。

你可能感兴趣的:(笔记,类,C++学习笔记)