面试时经常会遇到一道题,就是写一个简单的String类,很多人不假思索的就给出了下面这样的写法
class String
{
String(char* str)
:_str(new char[strlen(str)])
{}
String(const String& s)
:_str(s._str)
{}
String operator=(const String& s)
{
if (this != &s)
{
_str = s._str;
}
}
~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char* _str;
};
这是,offer就会跟你说拜拜了,这个代码存在很多问题,首先,没有默认的缺省构造函数,第二,在拷贝构造函数中采用的是浅拷贝,使得新拷贝出来的对象跟用来拷贝的参数指针指向了同一块空间,析构的时候会对着快空间析构两次,程序就会奔溃了,为了避免这种情况,我们就用拷贝的传统写法来实现一个简单的String类。
这里,我们先解释一下深拷贝和浅拷贝的概念
深拷贝:对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间
浅拷贝:在对象复制时,只是对对象中的成员进行简单的赋值
class String
{
public:
String(char* str = " ")
:_str(new char[strlen(str)+1])
{
strcpy(_str, str);
}
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
}
String operator=(const String& s)
{
if (this != &s)
{
char* tmp = new char[strlen(s._str) + 1];
strcpy(tmp, s._str);
delete[] _str;
swap(_str, tmp);
}
return *this;
}
~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char* _str;
};
这样就解决了拷贝构造后西通自动调用析构函数重复析构同一块空间的问题。这样,一个简单的String类就完成了。