如何理解深拷贝和浅拷贝

首先我们先记住一个结论:编译器自动生成的拷贝构造和赋值运算符是memcpy的一个过程。

实例过程以结构体代替,在c++中struct和class除了默认访问权限基本等同。 


struct TestStruct1
{
    int arr[3];
    int a;
};

int main()
{
   TestStruct1 oneVar;
   oneVar.arr[0]=1;
   oneVar.arr[1]=2;
   oneVar.arr[2]=3;
   oneVar.a=4;

   TestStruct1 twoVar=oneVar;
}

 拷贝构造直接将oneVar的内存空间拷贝到twoVar的内存空间中。

 考虑一个成员指针的情况:

struct TestStruct2
{
	int arr[3];
	int *a;
};

int main()
{
    TestStruct1 oneVar;
	oneVar.arr[0] = 1;
	oneVar.arr[1] = 2;
	oneVar.arr[2] = 3;
	oneVar.a = new int(4);

	TestStruct1 twoVar = oneVar;
}

 由此看出oneVar和twoVar的指针成员共享了oneVar.a的堆内存空间,如果oneVar和twoVar其中一个执行了delete oneVar.a或者

delete twoVar.a(4这块内存被回收了),这个时候另外一个变量再次从a取值就是产生未定义的行为。

为了解决上述共享堆内存而引发的未定义行为问题,引入了深拷贝

struct TestStruct3
{
	int arr[3];
	int *a;
    
    TestStruct3(){}

    TestStruct3(const TestStruct3& other)
    {
        this->arr[0]=other.arr[0];
        this->arr[1]=other.arr[1];
        this->arr[2]=other.arr[2];
        this->a = new int(*(other.a)); // 深拷贝解决的问题
    }
	~TestStruct3()
	{
		delete a; // 显式释放堆内存,否则默认的析构函数不会释放对内存
		a = nullptr;
	}
};

int main()
{
    TestStruct3 oneVar;
    oneVar.arr[0]=1;
    oneVar.arr[1]=2;
    oneVar.arr[2]=3;
    oneVar.a = new int(4);

    TestStruct3 twoVar = oneVar;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值