目录
浅拷贝
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
}
}
我们可以再次打开监视窗口,观察两个指针的值:
可以验证到确实是两块不同的空间了!