各位官爷先了解一下浅拷贝和深拷贝的概念。
浅拷贝
同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然 是独立的两个对象,这种情况被称为浅拷贝.一般情况下,浅拷贝没有任何副作 用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内存释放的处理,会导致内存问题,即多次释放同一地址空间,会出现段错误。
深拷贝
当类中有指针,并且此指针有动态分配空间,析构函数做了释放处理,往往需要自定义拷贝构造函数,自行给指针动态分配空间,即为深拷贝。
区别联系
看完之后,各位官爷是不是对他们有了一定的理解了呐,在我们日常的拷贝过程中直接用是完全没有问题的,没有浅拷贝和深拷贝之分~但是一旦遇到指针,哈哈哈,还要想堆区申请空间的,那您可得注意了呦,咱们本着“谁污染谁治理,谁申请谁释放的好孩子原则”在释放空间的时候它的魔爪便悄然来至,咳咳、、说正题,由于是完全复制,两个类指向堆区的空间地址一样,函数名却不一样,因此您在释放两个函数的时候看上去没毛病,挺完美的,但是却造成的同一堆区的地址空间多次释放,就必然出现段错误!
干说多没说服力,来,上酒!~
void test03()
{
DATA data1;
DATA data2;
data1.num = 100;
data1.name = (char *)calloc(1,10);
strcpy(data1.name,"my data");
printf("data1:num = %d, name = %s\n",data1.num, data1.name);
//指针变量 作为结构体的成员 结构体变量间的赋值操作 容易导致“浅拷贝”发生
data2 = data1;//“浅拷贝”
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;
}
}
运行结果:
那如何解决呐,官爷莫急,看下面:(这个我是采用c++中的类写的)
#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
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=(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)//拷贝构造函数
{
m_name=(char *)calloc(1,strlen(ob.m_name)+1);
if(m_name==NULL)
{
cout<<"函数拷贝空间申请失败"<<endl;
}
cout<<"空间已被申请"<<endl;
strcpy(m_name,ob.m_name);
m_num=ob.m_num;
cout<<"拷贝构造函数"<<endl;
}
~Person()
{
if(m_name!=NULL)
{
free(m_name);
m_name=NULL;
}
cout<<"析构函数"<<endl;
}
void showPoint()//遍历
{
cout<<"姓名:"<<m_name<<", num="<<m_num<<endl;
}
};
void test01()
{
Person lucy("lucy",100);
lucy.showPoint();
Person bob=lucy;
bob.showPoint();
}
int main(int argc, char *argv[])
{
test01();
return 0;
}
运行结果:
好了,本期就到这里了,创作不易,各位官爷给个点赞关注呀,爱你们~