在c++中,深拷贝和浅拷贝也算是一个难点,特别是对于初学者来说,往往在不知道两者区别的情况下而错误的使用了浅拷贝,从而导致了野指针之类的问题,但是又因为缺少理解所以很难定位到问题所在
类中有指针成员 才会讨论 浅拷贝 和深拷贝问题。
浅拷贝(单纯值拷贝)
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class Person
{
public:
char *m_name;
public:
Person(char *name)
{
cout<<"有参构造"<<endl;
m_name = (char *)calloc(1,strlen(name)+1);
if(m_name == NULL)
{
cout<<"空间申请失败"<<endl;
exit(-1);
}
strcpy(m_name, name);
}
~Person()
{
cout<<"析构函数"<<endl;
//释放指针成员 指向的堆区空间
if(m_name != NULL)
{
free(m_name);
m_name = NULL;
}
cout<<"-----001------"<<endl;
}
};
int main(int argc, char *argv[])
{
Person ob1("lucy");
Person ob2 = ob1;//拷贝构造(默认是浅拷贝)
cout<<"ob2.m_name = "<<ob2.m_name<<endl;
return 0;
}
深拷贝
必须在拷贝构造中给ob2.m_name申请空间
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class Person
{
public:
char *m_name;
public:
Person(char *name)
{
cout<<"有参构造"<<endl;
m_name = (char *)calloc(1,strlen(name)+1);
if(m_name == NULL)
{
cout<<"空间申请失败"<<endl;
exit(-1);
}
strcpy(m_name, name);
}
Person(const Person &ob)
{
cout<<"拷贝构造函数(深拷贝)"<<endl;
m_name = (char *)calloc(1, strlen(ob.m_name)+1);
if(m_name == NULL)
{
cout<<"空间申请失败"<<endl;
exit(-1);
}
strcpy(m_name, ob.m_name);
}
~Person()
{
cout<<"析构函数"<<endl;
//释放指针成员 指向的堆区空间
if(m_name != NULL)
{
free(m_name);
m_name = NULL;
}
}
};
int main(int argc, char *argv[])
{
Person ob1("lucy");
Person ob2 = ob1;//拷贝构造
cout<<"ob2.m_name = "<<ob2.m_name<<endl;
return 0;
}
总结
1、如果类中的成员 指向了堆区空间 一定要记得在析构函数中 释放该空间
2、如果用户 不实现 拷贝构造 系统就会提供默认拷贝构造,而默认拷贝构造 只是单纯的赋值 容易造成浅拷贝问题
3、用户记得 要实现:无参构造(初始化数据)、有参构造(赋参数)、拷贝构造(深拷贝) 、析构函数(释放空间)
拷贝构造函数的调用时机
拷贝构造函数调用的时机:旧对象 给新对象 初始化
class Data
{
public:
Data()
{
cout<<"无参构造"<<endl;
}
Data(const Data &ob)
{
cout<<"拷贝构造"<<endl;
}
~Data()
{
cout<<"析够函数"<<endl;
}
};
情形1:旧对象给新对象初始化
Data ob1;
Data ob2 = ob1;//调用拷贝构造
情形2:普通对象作为函数的参数
void fun01(Data ob)//Data ob=ob1 发生拷贝构造
{
}
int main(int argc, char *argv[])
{
Data ob1;
fun01(ob1);
return 0;
}
情形3:普通对象 作为函数的返回值
#include <iostream>
using namespace std;
Data fun01(void)
{
Data ob1;
return ob1;
}
int main(int argc, char *argv[])
{
Data ob = fun01();
return 0;
}
vs下会发生拷贝构造:
Qt、linux不会发生拷贝:
到此这篇关于C++简明图解分析浅拷贝与深拷贝的文章就介绍到这了,更多相关C++浅拷贝与深拷贝内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
沃梦达教程
本文标题为:C++简明图解分析浅拷贝与深拷贝


猜你喜欢
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- ubuntu下C/C++获取剩余内存 2023-09-18
- C语言qsort()函数的使用方法详解 2023-04-26
- C语言详解float类型在内存中的存储方式 2023-03-27
- Easyx实现扫雷游戏 2023-02-06
- C++ 数据结构超详细讲解顺序表 2023-03-25
- Qt计时器使用方法详解 2023-05-30