IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++构造函数的浅拷贝与深拷贝 -> 正文阅读

[C++知识库]C++构造函数的浅拷贝与深拷贝


前言

上期讲到构造函数,本期接着讲


本文章为初学者为巩固知识所创作,知识有限,大佬轻喷

一、编译器默认提供的构造函数

首先来看一段代码

class MyClass
{
public:
	int i;
	char c;
	string str;

};

void main()
{
	MyClass class1;

	cout << class1.i << " ";
	cout << class1.c << " ";
	cout << class1.str << " ";
	cout << endl;
}

解释一下写这段代码的原因:
首先定义一个MyClass类,
内部并没有定义任何构造函数,那么内部的变量的值是多少呢?
我们调用一下test函数

运行截图
结果可以发现,内部变量是随机值

那我们实现一个有参构造函数呢

class MyClass
{
public:
	int i;
	char c;
	string str;

	MyClass(int i, char c, string str)
	{
		;
	}
};

void test()
{
	MyClass class1;

	cout << class1.i << " ";
	cout << class1.c << " ";
	cout << class1.str << " ";
	cout << endl;
}

定义了一个有参构造函数,但内部没有任何函数实现

再次调用test函数
在这里插入图片描述
报错了
错误为MyClass没有默认构造函数
那为什么定义一个有参构造函数后就报错了呢?

在这里插入图片描述
因为在自己没有实现任何构造函数时,编译器会自己实现三个空构造函数,而当自己实现了构造函数后,就会发生变化

如何再加上这段代码

MyClass class1;	
MyClass class2(1, '2', "abc");
MyClass class3(class2);

创建对象class1时报错,class3时没有报错。

所以可见编译器提供了拷贝构造函数,没有提供无参构造函数
这种构造函数叫‘隐式构造’
当自己没有实现任何构造函数时,类会提供3种隐式构造函数
自己实现了有参构造后,类则不会提供隐式默认无参构造
当自己实现拷贝构造函数后,类不会提供任何隐式构造函数

二、浅拷贝与深拷贝

老规矩,上代码

class MyClass
{
public:
	int i;
	char c;
	string str;

	MyClass(int i, char c, string str)
	{
		this->i = i;
		this->c = c;
		this->str = str;
	}
};

void test()
{
	MyClass class1(1, 'c', "abc");
	MyClass class2(class1);

	cout << "class2内部变量为:";
	cout << "i = " << class2.i << "  ";
	cout << "c = " << class2.c << "  ";
	cout << "str = " << class2.str << "  ";
	cout << endl;
}

调用test函数
运行结果:
在这里插入图片描述
上述代码我们使用编译器提供的拷贝构造函数初始化class2,并没有任何问题

那么我们如果把成员变量存放到堆区呢

class MyClass2
{
public:
	int* arr;

	MyClass2()
	{
		arr = new int[4];
		for (int i = 0; i < 4; i++)
			arr[i] = i;
	}

	void show()
	{
		for (int i = 0; i < 4; i++)
			cout << arr[i] << " ";
		cout << endl;
	}
};

void test2()
{
	MyClass2 class1;
	MyClass2 class2(class1);
	cout << "class1 修改前 class2 内部arr数据为:";
	class2.show();
	
	for (int i = 0; i < 4; i++)
		class1.arr[i] = i + 1;
	cout << "class1 修改后 class2 内部arr数据为:";
	class2.show();
}

int main()
{
	test2();
	return 0;
}

MyClass2中arr是堆区数组,我们通过默认构造对class1进行初始化,此时class1.arr中数据为 0,1, 2, 3

再通过默认的拷贝构造对class2进行初始化,那么class2.arr中数据肯定也为 0,1, 2, 3

用下面的代码修改class1中的数据

for (int i = 0; i < 4; i++)
		class1.arr[i] = i + 1;

修改后为 1, 2, 3, 4
我们执行代码看看class2中数据为多少

在这里插入图片描述
class2 为什么也改变了呢
在这里插入图片描述

用图片来解释吧

在这里插入图片描述
编译器默认的拷贝构造执行了
class2.arr = class1.arr;
这样的操作二者指向同一块内存区域,修改class1,class2 也会改变

编译器默认的拷贝构造函数为浅拷贝
那么如何解决这种浅拷贝的问题呢

当然是自己实现拷贝构造函数啦
在这里插入图片描述

在这里插入图片描述
只要自己实现拷贝构造函数让堆区的数据也拷贝过来就行了
思路简单,直接上代码

MyClass2(MyClass2& cla)
{
	this->arr = new int[sizeof(cla.arr)];
	for (int i = 0; i < sizeof(cla.arr); i++)
		this->arr[i] = cla.arr[i];
}

执行效果:
在这里插入图片描述

OK,完了,下期写点什么好呢,简单写写运算符重载吧(反正没人看

请添加图片描述
都看到这了点个赞呗
下期再见

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 12:59:34  更:2021-09-12 12:59:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:55:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码