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

 更新时间:2022年05月27日 10:00:21   作者:对象new不出来  
C++对象特性里的拷贝构造函数有更深入的含义,而且面试曾经问过关于拷贝的析构问题,那么今天就好好解析一下深浅拷贝的问题;还有初始化列表的形式,这个在给对象属性初始化的时候非常方便,建议大家熟练掌握,话不多说,开始正文

深浅拷贝区别

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

代码解释

#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++深浅拷贝内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++异步调用方法详解

    C++异步调用方法详解

    这篇文章主要介绍了C++异步调用方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • Qt线程池QThreadPool的使用详解

    Qt线程池QThreadPool的使用详解

    本文主要介绍了Qt线程池QThreadPool的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C++智能指针shared_ptr与weak_ptr的实现分析

    C++智能指针shared_ptr与weak_ptr的实现分析

    shared_ptr是一个标准的共享所有权的智能指针,允许多个指针指向同一个对象,定义在 memory 文件中,命名空间为 std,这篇文章主要介绍了C++ 中 shared_ptr weak_ptr,需要的朋友可以参考下
    2022-09-09
  • undefined reference to `SetPduPowerConsumptionCnt''错误的解决方法

    undefined reference to `SetPduPowerConsumptionCnt''错误的解决方法

    编译时出现undefined reference to `SetPduPowerConsumptionCnt'错误要如何解决呢?有没有什么好的解决方法?下面小编就为大家解答吧,如果你也遇到了这种情况,可以过来参考下
    2013-07-07
  • C++编程模板匹配超详细的识别手写数字实现示例

    C++编程模板匹配超详细的识别手写数字实现示例

    大家好!本篇文章是关于手写数字识别的,接下来我将在这里记录我的手写数字识别的从零到有,我在这里把我自己的写代码过程发出来,希望能帮到和我一样努力求知的人
    2021-10-10
  • C语言读取文件流的相关函数用法简介

    C语言读取文件流的相关函数用法简介

    这篇文章主要介绍了C语言读取文件流的相关函数用法简介,包括fread()函数和feof()函数的使用,需要的朋友可以参考下
    2015-08-08
  • C++基于栈的深搜算法实现马踏棋盘

    C++基于栈的深搜算法实现马踏棋盘

    这篇文章主要为大家详细介绍了C++基于栈的深搜算法实现马踏棋盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C++实现LeetCode(17.电话号码的字母组合)

    C++实现LeetCode(17.电话号码的字母组合)

    这篇文章主要介绍了C++实现LeetCode(17.电话号码的字母组合),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Linux配置C++11编译环境的方法

    Linux配置C++11编译环境的方法

    这篇文章主要介绍了Linux配置C++11编译环境,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • C++的函数与指针

    C++的函数与指针

    今天小编就为大家分享一篇关于C++函数与指针的文章,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2021-10-10

最新评论