0
点赞
收藏
分享

微信扫一扫

深浅拷贝问题

目录

浅拷贝

深拷贝


 

浅拷贝

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

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

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

举报

相关推荐

0 条评论