文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++细讲深浅拷贝与初始化列表如何操作

2024-04-02 19:55

关注

深浅拷贝区别

上一节简单提了编译器会默认给我们提供值拷贝构造函数,结果是新的对象会拥有和传入对象一样的属性,由编译器提供的拷贝构造被称为浅拷贝构造,而由我们自己编写的不同于编译器提供的拷贝构造函数就叫深拷贝构造了,举个典型的例子说明。

代码解释

#include<iostream>
using namespace std;
//深浅拷贝问题,存在经典的坑,面试考过
class Person
{
public:
	Person(int age,int height)
	{
		m_age = age;
		m_Height = new int(height);
		cout << "Person 的有参构造函数调用" << endl;
	}
	//自己写不同于编译器的拷贝构造函数属于深拷贝
	Person(const Person& p)
	{
		cout << "拷贝构造函数调用" << endl;
		m_age = p.m_age;
		//m_Height = p.m_Height;
		
		m_Height =new int(*p.m_Height);
	}
	~Person()
	{
		//析构代码,将堆区开辟的数据做释放操作
		if (m_Height != NULL)
		{
			delete m_Height;
			m_Height = NULL;
		}
		cout << "~Person 的析构构造函数调用"<<endl;
	}
	int m_age;
	int* m_Height;
};
void test()
{
	Person p1(20,180);
	Person p2(p1);
	cout << "p2.age= " << p2.m_age << " p2.height=" << *p2.m_Height << endl;
}
int main()
{
	test();
	system("pause");
}

创建Person类,设置m_age和指针类型*m_Height为私有属性;依次对Person类设置有参构造和拷贝构造函数以及析构函数;前面析构函数一直没有什么作用,其实它是用来清理对象的,析构函数会在程序结束前自动调用,这时候就可以使用delete清理掉;

特别注意

Person(const Person& p)
	{
		cout << "拷贝构造函数调用" << endl;
		m_age = p.m_age;
		//m_Height = p.m_Height;
		
		m_Height =new int(*p.m_Height);
	}
	~Person()
	{
		//析构代码,将堆区开辟的数据做释放操作
		if (m_Height != NULL)
		{
			delete m_Height;
			m_Height = NULL;
		}
		cout << "~Person 的析构构造函数调用"<<endl;
	}

这里不能使用编译器提供的浅拷贝,如果直接使用m_Height=p.m_Height,毫无疑问这两个属性地址相同,那么在调用析构函数的时候,p1先释放内存,这时候虽然有一个NULL判断,但是此块内存已经被删除,再次访问都会提示错误,这是很危险的,所以我们需要用深拷贝解决重复删除的问题。使用m_Height=new int(*p.m_Height) 语句给身高属性重新开辟空间,这样在调用析构的时候各自清理各自的属性,就解决了这个浅拷贝带来的重复清理问题。

内存图解释

上面是浅拷贝的p1、p2对象的内存示意图,两次析构会重复当问0x00011地址,但是当这个地址被删除后,是不允许再次访问的。

利用我们设置的深拷贝构造后,地址不一样,各自删除各自的地址,解决问题

初始化列表

初始化列表用来给属性初始化

语法

普通构造函数+:+ 类属性(变量或常量)+ {}

具体实现

class Person
{
public:
	Person() :m_age(20), m_sex(1), m_height(180){}
	Person(int a, int b, int c) :m_age(a), m_sex(b), m_height(c){}
	int m_age;
	int m_sex;
	int m_height;
};
int main()
{
	Person p1;
	Person p2(10, 20, 30);
	cout << "年龄为:" << p1.m_age;
	cout << "性别为:" << p1.m_sex;
	cout << "身高为:" << p1.m_height<<endl;
	cout << "年龄为:" << p2.m_age;
	cout << "性别为:" << p2.m_sex;
	cout << "身高为:" << p2.m_height << endl;;
}

主函数中p1调用无参构造函数,各属性初始化为属性()括号里面的值;p2调用有参构造函数,将实参10,20,30分别传给a,b,c,然后a的值传给m_age,b的值传给m_sex;c的值传给m_height;直接来看结果:

总结

C++对象特性的深浅拷贝和初始化列表到这里就分享完了,那麽意味着对象的初始化和清理就结束了,到后面会讲一下静态成员和类对象作为类成员的一个案例,用于巩固这部分知识点,希望下篇文章也可以得到你们的青睐

到此这篇关于C++细讲深浅拷贝与初始化列表如何操作的文章就介绍到这了,更多相关C++深浅拷贝内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯