关于浅拷贝和深拷贝,你了解多少???赶紧补习,避免入坑

各位官爷先了解一下浅拷贝和深拷贝的概念。

浅拷贝

同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然 是独立的两个对象,这种情况被称为浅拷贝.一般情况下,浅拷贝没有任何副作 用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内存释放的处理,会导致内存问题,即多次释放同一地址空间,会出现段错误。

深拷贝

当类中有指针,并且此指针有动态分配空间,析构函数做了释放处理,往往需要自定义拷贝构造函数,自行给指针动态分配空间,即为深拷贝。

区别联系

看完之后,各位官爷是不是对他们有了一定的理解了呐,在我们日常的拷贝过程中直接用是完全没有问题的,没有浅拷贝和深拷贝之分~但是一旦遇到指针,哈哈哈,还要想堆区申请空间的,那您可得注意了呦,咱们本着“谁污染谁治理,谁申请谁释放的好孩子原则”在释放空间的时候它的魔爪便悄然来至,咳咳、、说正题,由于是完全复制,两个类指向堆区的空间地址一样,函数名却不一样,因此您在释放两个函数的时候看上去没毛病,挺完美的,但是却造成的同一堆区的地址空间多次释放,就必然出现段错误!
干说多没说服力,来,上酒!~

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;
}

运行结果:
在这里插入图片描述
好了,本期就到这里了,创作不易,各位官爷给个点赞关注呀,爱你们~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值