深浅拷贝问题

目录

浅拷贝

深拷贝


 

浅拷贝

浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规。要解决浅拷贝问题,C++中引入了深拷贝。

namespace sjj
{
	class string
	{
	public:
		string(const char* str)
			:_str(new char[strlen(str)+1])// \0
		{
			strcpy(_str,str);//char *strcpy( char *strDestination, const char *strSource );
		}
		//此处没有写拷贝构造函数,会使用编译器默认生成的拷贝构造函数
        //对于内置类型char* 完成值拷贝
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
	private:
		char* _str;
	};
	void test()
	{
		string s1("hello");
		string s2(s1);
	}
}

浅拷贝就是值拷贝,像memcpy一样,只是把数据给拷贝过去

通过调试,在监视窗口我们也能验证确实两个指针的地址是一样的

这样就会在最后调用析构函数的时候出现问题后定义的对象先析构,释放指针资源,s2的_str先释放了,但是两个对象里面的_str是一样的,当后析构释放s1的_str时候,s1的_str指向一块已经释放过的空间,现在它相对于野指针了,释放野指针就会导致程序崩溃

事实上我们想要达成的目标是,两个对象中的_str分别指向两块不同的空间,拷贝时再将数据拷贝到另外一块空间上面去,这里就要引出我们的深拷贝了 

深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式(就是要手动写,不能用编译器自动生成的)给出。一般情况这些函数都是按照深拷贝方式提供。

 这样一来两块空间相互独立,s2的_str和s1的_str调用析构函数释放资源时互不影响,各种对于数据的增删查改也不会影响

  所以对于string类这样的类,我们就不能用编译器默认生成的,因为是值拷贝的,所以我们要自己手动写

namespace sjj
{
	class string
	{
	public:
		string(const char* str)
			:_str(new char[strlen(str)+1])// \0
		{
			strcpy(_str,str);//char *strcpy( char *strDestination, const char *strSource );
		}
		//要用自己写的
		string(const string& s)
			:_str(new char[strlen(s._str)+1])
		{
			strcpy(_str,s._str);
		}
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
	private:
		char* _str;
	};
	void test()
	{
		string s1("hello");
		string s2(s1);//correct
	}
}

我们可以再次打开监视窗口,观察两个指针的值:

可以验证到确实是两块不同的空间了! 

  • 26
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值