【C++之浅拷贝和深拷贝】举例对象内数组的拷贝

首先先谈动态内存分配,主要是在程序运行期间,申请内存空间,用到操作符new,例如申请一个数组空间:int *arr = new int[10];,指针arr指向数组空间的初始地址即首元素地址;
当使用完动态内存分配的空间后,如若不需要再使用,应该主动释放掉,否则容易导致内存泄漏。释放内存操作符delete:例如释放数组空间:delete[] arr;,对于对象内存释放:delete 指针p
谈浅拷贝:只能实现对象间数据元素的一一对应的复制,而对于指针来说,只拷贝了指针本身,但没有拷贝指针所指向的对象,因此倘若改变原数据,则副本也会受到影响,因为两者指针指向了相同的内存空间。
谈深拷贝:当被复制的对象数据成员是指针类型时,不应该只是复制该指针成员本身,而是要将指针所指的对象进行复制,其中要涉及到用new为副本开辟新的内存空间,只有这样,原数据与副本虽然最初内容相同,但是两者所占的内存位置完全不同,并不会互相影响。
举例如下:
首先先观察浅拷贝的结果(如下程序),从输出结果可以看出,a2是对a1进行的浅拷贝,只是拷贝了数组arr指针的本身,因为当对a1数组进行修改时,a2的数组也受到了影响,因为两个所指向的内存空间一致。

class A {
public:
	int *arr;
	A(int n) {//构造函数
		arr = new int[n];
	}
	A(const A& a) {//复制构造函数
		arr = a.arr;
	}
};

int main() {
	A a1(1);
	a1.arr[0] = 1;
	printf("对象a1的数据:%d\n", a1.arr[0]);
	A a2 = a1;
	printf("对象a2的数据:%d\n", a2.arr[0]);
	a1.arr[0] = 2;//对象a1数据修改为2
	printf("仅对象a1数据修改后:\n");
	printf("对象a1的数据:%d\n", a1.arr[0]);
	printf("对象a2的数据:%d\n", a2.arr[0]);
}
/*输出
对象a1的数据:1
对象a2的数据:1
仅对象a1数据修改后:
对象a1的数据:2
对象a2的数据:2
*/

接下来,举例深拷贝,修改一下上面代码为,从输出结果可以看出,深拷贝实现了两个对象的数组分别占用不同的内存空间,因为两个不会互相影响。

class A {
public:
	int *arr;
	A(int n) {//构造函数
		arr = new int[n];
	}
	A(const A& a) {//复制构造函数
		int n = sizeof(a.arr) / 4;
		arr = new int[n];
		for (int i = 0; i < n; i++) {
			arr[i] = a.arr[i];
		}
	}
};

int main() {
	A a1(1);
	a1.arr[0] = 1;
	printf("对象a1的数据:%d\n", a1.arr[0]);
	A a2 = a1;
	printf("对象a2的数据:%d\n", a2.arr[0]);
	a1.arr[0] = 2;//对象a1数据修改为2
	printf("仅对象a1数据修改后:\n");
	printf("对象a1的数据:%d\n", a1.arr[0]);
	printf("对象a2的数据:%d\n", a2.arr[0]);
}
/*输出:
对象a1的数据:1
对象a2的数据:1
仅对象a1数据修改后:
对象a1的数据:2
对象a2的数据:1(update)
*/
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值