浅拷贝和深拷贝

1.浅拷贝

首先我们先来看这段代码,我们用s1给s2进行拷贝构造,此时我们没有自己写拷贝构造,那么编译器会默认生成。 

class String
{
public:
	String(const char* ptr = "")
	{
		if (ptr == NULL)
			ptr = "";
		_ptr = new char[strlen(ptr) + 1];
		strcpy(_ptr, ptr);
	}
	~String()
	{
		if (_ptr){
			delete[] _ptr;
		}
	}
private:
	char* _ptr;
};
void test(){

	String s1("hello");
	String s2(s1);

}

此时我们运行程序发现会崩掉。为什么呢?

我们查看了一下两个对象的地址,发现是一样的。 

 

 

在类里面有指针对象的时候,默认的拷贝构造只是进行值拷贝,两个对象公用一块空间,因此在对象销毁的时候就会发生内存违规。

那么上面说的这种就是浅拷贝:也称为位拷贝。编译器只是将对象中的值采用基本类型值复制的方式拷贝过来,如果对象中管理资源,最后就导致多个对象共享一份资源,当一个对象销毁的时候就会将该资源释放掉,但是另一个对象不知道该资源已经释放,以为还有效,继续对资源进行操作,发生访问违规。

那么这种问题我们应该如何解决?采用深拷贝。

 

 2.深拷贝

深拷贝是拷贝对象具体的内容,内存空间会自主分配,拷贝结束后,虽然两个存的值相同,但是地址不同,两个对象互不影响。 

此时我们自己写了一个拷贝构造函数,先申请一块相同大小的空间,然后再将内容拷过来。 

	String(const String& str)
	:	_str(new char[strlen(str._str) + 1])
	{	
	 strcpy(_str, str._str);
	}

此时我们看到两个的内存地址不相同,在做析构的时候也不影响。 

对于赋值操作符也是一样的道理,我们必须自己来写

	//返回值为引用是因为要连续赋值,参数为引用是为了少调用一次拷贝构造  返回值为this指针也是为了连续赋值
	String& operator=(const String& str)
	{
		//不能自己给自己赋值
		if (this != &str)
		{
			//先申请空间
			char* tmp = new char[strlen(str._str) + 1];
			//将str的内容拷给tmp
			strcpy(tmp, str._str);
			//将原有的空间释放
			delete[] _str;
			//再将tmp里面的字符串目标对象
			_str = tmp;
			return *this;
		}
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值