C++面试题之浅拷贝和深拷贝的区别「建议收藏」

C++面试题之浅拷贝和深拷贝的区别「建议收藏」先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。先看一个例子,有一个学生类,数据成员时学生的人数和名字:#include<iostream>usingnamespacestd;classStudent{private: intnum; c…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

       先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。

       先看一个例子,有一个学生类,数据成员时学生的人数和名字:

#include <iostream>  
using namespace std;

class Student
{
private:
	int num;
	char *name;
public:
	Student();
	~Student();
};

Student::Student()
{
	name = new char(20);
	cout << "Student" << endl;

}
Student::~Student()
{
	cout << "~Student " << (int)name << endl;
	delete name;
	name = NULL;
}

int main()
{
	{// 花括号让s1和s2变成局部对象,方便测试
		Student s1;
		Student s2(s1);// 复制对象
	}
	system("pause");
	return 0;
}

C++面试题之浅拷贝和深拷贝的区别「建议收藏」
       执行结果:调用一次构造函数,调用两次析构函数,两个对象的指针成员所指内存相同,这会导致什么问题呢?name指针被分配一次内存,但是程序结束时该内存却被释放了两次,会导致崩溃!

C++面试题之浅拷贝和深拷贝的区别「建议收藏」

 

       这是由于编译系统在我们没有自己定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行的是浅拷贝!即对指针name拷贝后会出现两个指针指向同一个内存空间。

 

C++面试题之浅拷贝和深拷贝的区别「建议收藏」

       所以,在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生。

        添加了自己定义拷贝构造函数的例子:

#include <iostream>  
using namespace std;

class Student
{
private:
	int num;
	char *name;
public:
	Student();
	~Student();
	Student(const Student &s);//拷贝构造函数,const防止对象被改变
};

Student::Student()
{
	name = new char(20);
	cout << "Student" << endl;

}
Student::~Student()
{
	cout << "~Student " << (int)name << endl;
	delete name;
	name = NULL;
}
Student::Student(const Student &s)
{
	name = new char(20);
	memcpy(name, s.name, strlen(s.name));
	cout << "copy Student" << endl;
}

int main()
{
	{// 花括号让s1和s2变成局部对象,方便测试
		Student s1;
		Student s2(s1);// 复制对象
	}
	system("pause");
	return 0;
}

C++面试题之浅拷贝和深拷贝的区别「建议收藏」
        执行结果:调用一次构造函数,一次自定义拷贝构造函数,两次析构函数。两个对象的指针成员所指内存不同。
 总结:浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
再说几句:
当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形:
1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现;
2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。

 

3.浅拷贝带来问题的本质在于析构函数释放多次堆内存,使用std::shared_ptr,可以完美解决这个问题。

 

关于std::shared_ptr的原理和实现可参考:C++笔试题之smart pointer的实现

一个完整的自定义类实现可参考:C++笔试题之String类的实现

 

参考链接:https://www.cnblogs.com/always-chang/p/6107437.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186966.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • id门禁卡复制到手机_门禁卡复制到手机苹果

    id门禁卡复制到手机_门禁卡复制到手机苹果大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。门禁卡复制到苹果手机的步骤如下:1、首先读取卡的ID,并安装“NFCTagInfo”,打开手机的NFC设置,门禁卡贴到手机后盖NFC部分,“NFCTagInfo”读取校园卡ID。可以看到“我的卡”ID号码。2、其次修改手机NFC的ID。随即打开R.E.管理器,根目录etc,找到etc文件夹中的“libnfc-nxp.conf”…

  • Mysql开启远程连接方法

    Mysql开启远程连接方法

  • DirBuster使用教程

    DirBuster使用教程工具是kali自带,多用于网站的后台扫描工具路径:/usr/share/dirbustercd/usr/share/dirbuster进入路径后ls查看,会看到目录下的jar文件:2.java-jarDirBuster-1.0-RC1.jar打开jar文件3.出现可视化窗口,配置很多,现在我们先填写空白的输入框部分,这里我们在第一个输入框填写扫描网站的url地址4….

    2022年10月26日
  • mysql mycat读写分离_mycat读写分离原理

    mysql mycat读写分离_mycat读写分离原理MyCat的说明文档请参见主要使用到得几个配置文件有schema.xml、rule.xml、server.xmlMYCAT_HOME/conf/schema.xml中定义逻辑库,表、分片节点等内容.MYCAT_HOME/conf/rule.xml中定义分片规则.MYCAT_HOME/conf/server.xml中定义用户以及系统相关变量,如端口等.假设有如下几个数据库,arp库是a库的复制…

  • USB转RS485/RS422接线说明

    USB转RS485/RS422接线说明       

  • UVa – The 3n + 1 problem 解读

    UVa – The 3n + 1 problem 解读

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号