深拷贝和浅拷贝
别人再好,也是别人。自己再不堪,也是自己,独一无二的自己。只要努力去做最好的自己,一生足矣。为自己的人生负责,为自己的梦想买单。
1、浅拷贝
同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然 是独立的两个对象,这种情况被称为浅拷贝.一般情况下,浅拷贝没有任何副作 用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内 存释放的处理,会导致内存问题。
2、深拷贝
当类中有指针,并且此指针有动态分配空间,析构函数做了释放处 理,往往需要自定义拷贝构造函数,自行给指针动态分配空间,深拷贝。
案例:浅拷贝
如果类中的成员 指向了堆区空间 一定要记得在析构函数中 释放该空间
如果用户 不实现 拷贝构造 系统就会提供默认拷贝构造
而默认拷贝构造 只是单纯的赋值 容易造成浅拷贝问题
用户记得 要实现:无参构造(初始化数据)、有参构造(赋参数)、拷贝构造(深拷贝) 、析构函数(释放空间)
class Person
{
private:
char *m_name;
int m_num;
public:
Person()
{
m_name = NULL;
m_num = 0;
cout<<"无参构造"<<endl;
}
Person(char *name,int num)
{
//为m_name申请空间
m_name = (char *)calloc(1,strlen(name)+1);
if(m_name == NULL)
{
cout<<"构造失败"<<endl;
}
cout<<" 已经申请好空间"<<endl;
strcpy(m_name,name);
m_num = num;
cout<<"有参构造"<<endl;
}
Person(const Person &ob)//ob==>lucy
{
cout<<"拷贝构造函数"<<endl;
m_name = (char *)calloc(1, strlen(ob.m_name)+1);
cout<<"空间已被申请"<<endl;
strcpy(m_name, ob.m_name);
m_num = ob.m_num;
}
~Person()
{
if(m_name != NULL)
{
cout<<"空间已被释放"<<endl;
free(m_name);
m_name = NULL;
}
cout<<"析构函数"<<endl;
}
void showPerson(void)
{
cout<<"m_name = "<<m_name<<", m_num = "<<m_num<<endl;
}
};
void test01()
{
Person lucy("lucy",100);
lucy.showPerson();
//浅拷贝的问题(多次释放同一块堆区空间)
//通过自定义 拷贝构造函数 完成深拷贝动作
Person bob = lucy;//调用系统的默认拷贝构造(单纯的值拷贝)
}
案例:深拷贝
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
int num;
char *name;
}DATA;
void test01()
{
DATA data1;
DATA data2;
data1.num = 100;
data1.name = (char *)calloc(1,12);
strcpy(data1.name, "my data");
data2.num = data1.num;
//为结构体变量 申请 独立的空间
data2.name = (char *)calloc(1,12);
strcpy(data2.name, data1.name);
printf("data1:num = %d, name=%s\n", data1.num, data1.name);
printf("data2:num = %d, name=%s\n", data2.num, data2.name);
if(data1.name != NULL)
{
free(data1.name);
data1.name = NULL;
}
if(data2.name != NULL)
{
free(data2.name);
data2.name = NULL;
}
}
int main(int argc,char *argv[])
{
test01();
return 0;
}
运行结果: