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++之构造函数(2)深拷贝和浅拷贝 -> 正文阅读

[C++知识库]C++之构造函数(2)深拷贝和浅拷贝

浅拷贝和深拷贝,在属性有堆区开辟,一定要自己提供拷贝构造函数。

重点看程序注释!

#include <iostream>
#include<string>

using namespace std;


class Person {
public:
	
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int a) {
		age = a;
		cout << "有参构造函数!" << endl;
	}
	Person(int a,int h) {
		age = a;
		height = new int(h);//因为我在属性那建立了一个指针,指针只能接受地址,所以我传过来的h,通过开辟堆区空间
		//运算的结果是一个地址,所以用指针来接收,你如果不在程序中释放空间,这个程序一定能跑,但是,当你释放空间
		//的时候,要注意释放的时机。
		cout << "两参数的有参构造函数!" << endl;
	}
	//拷贝构造函数(先跳到59行看)
	Person(const Person& p) {
		age = p.age;
		//height = p.height;//可以看做是编译器出来的默认拷贝,但是刚也说了,要实现深拷贝,你现在这个只是浅拷贝
		height = new int(*p.height);//要注意是解引用,因为我是重新把你的值找一个地址的
		cout << "深拷贝构造函数!" << endl;
	}
	//析构函数
	~Person() {
		if (height != NULL)
		{
			delete height;
			height = NULL;//为了防止野指针出现,就将他置空
		}
		cout << "析构函数!" << endl;
	}
private:
	int age;
	int* height;
};



//调用有参的构造函数
void test01() {
	Person p1(18);
	Person p2(p1);//走的是拷贝构造函数,但是因为程序员没有设置拷贝构造,所以编译器按默认的拷贝构造函数,走,所以数出来的p2.age也是18
	//
}

void test02() {
	//现在建立两个参数的有参构造
	Person p3(18, 15);

	//调用结束,Person局部变量被释放,因此此时的15的在此时释放比较好,所以要回到类的析构函数中去释放
	//**********以下为关键部分内容,当有成员属性在堆区开辟的时候,涉及调用拷贝构造函数,在释放的时候就要出问题******************
	Person p4(p3);
//问题在哪?
//问题在于根据进栈顺序,先进后出,p4的变量先释放,即p4的析构函数被调用,函数体中有一段释放堆区内存的程序,因此p4按照逻辑就把15的内存空间给释放了
//而当p3去运行那段程序时,height的内存早已被释放了,因为程序崩溃!【重复释放内存】
//解决措施:在p4在进行p3拷贝的时候呢,调用自己构造的拷贝函数的时候直接让你那个height换一个地址,这样在释放的时候就各走各的了,实现深拷贝,但你要不在堆区释放空间,就没那么多事吧
}

int main() {

	
	//test01();
	test02();
	system("pause");

	return 0;
}

//如果在类对象属性的定义时,在堆区开辟了空间,那么一定要自己提供拷贝构造函数,实现深拷贝,即第30行的代码,防止浅拷贝带来的问题

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 11:45:05  更:2021-09-30 11:47:46 
 
开发: 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年5日历 -2024/5/19 23:20:25-

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