浅拷贝如图所示,定义的俩个变量同时指向同一块空间,这样析构时就会出错
浅拷贝的实现:
class String
{
public:
String(char* str =" ")//构造
:_str(str)
{
cout << "String()" << endl;
}
String(const String& s)//浅拷贝
{
cout << "浅拷贝" << endl;
_str = s._str;
}
~String()
{
cout << "~String" << endl;
delete[] _str;
_str = NULL;
}
private:
char* _str;
};
int main()
{
String t1;
String t2(t1);
system("pause");
return 0;
}
同一块空间释放俩次时就会奔溃
深拷贝就是用来解决这一问题的,在拷贝的同时开一块空间
传统写法:
class String
{
public:
String(const char* str = " ")
{
if (str == NULL)
{
_str = new char[1];
*_str = '\0';
}
else
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
}
String(const String& str)
:_str(NULL)
{
if (str._str != NULL)
{
_str = new char[strlen(str._str)+1];
strcpy(_str, str._str);
}
}
//赋值运算符重载
String &operator=(const String str)
{
if (_str == NULL)//原来的为空就不需要delete
{
_str = new char[strlen(str._str)+1];
strcpy(_str, str._str);
}
/*else
{
delete[] _str; //delet原来的
_str = new char[strlen(str._str) + 1];//构建新的空间
strcpy(_str, str._str);拷贝
} 构建新空间时可能会没有开成功
*/
else//原来的不为空需要delete,但要先创建好空间否则会出错
{
char* tmp = new char[strlen(str._str) + 1];
strcpy(tmp, str._str);
delete _str;
_str = tmp;
}
return *this;
}
~String()//析构函数
{
if (_str != NULL)
{
delete[] _str;
_str = NULL;
}
}
private:
char *_str;
};
现代写法:
class String
{
public:
String(const char* str=" ")
{
if (str == NULL)
{
_str = new char[1];
*_str = '/0';
}
else
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
}
String(const String& s)
:_str(NULL)//重要
{
String tmp(s._str);
swap(_str, tmp._str);
}
String &operator=(const String s)
{
if (_str != s._str)
{
String tmp(s);
swap(_str, tmp._str);
}
return *this;
}
~String()
{
if (_str != NULL)
{
delete[] _str;
_str = NULL;
}
}
private:
char *_str;
};