要求:写出一个String类的赋值运算符函数
注意事项:
(1)返回值的类型需声明为该类型的引用,并在函数结束前返回实例自身的引用(即*this),因为只有返回一个引用,才可以允许连续赋值。
(2)传入参数必须为常量的引用。常量确保在函数内不改变传入实例的状态,而引用避免调用复制构造函数,以提高代码的效率。
(3)判断传入的参数和当前实例是否是同一个实例,以免在此时出现删除自身内存的情况。
(4)释放实例自身已有的内存,避免出现内存泄露。
代码如下:
String& String::operator=(const String &another)//注意返回类型写在前面
{
if(&another==this)
{
return *this;
}
delete [] m_data;
m_data=NULL;
m_data=new char[strlen(another.m_data)+1];
strcpy(m_data,another.m_data);
return *this;
}
另有考虑异常安全性的程序写法,该写法可以避免以下情况:在分配内存之前先delete了实例m_data的内存,而后续new char分配内存时内存不足,抛出异常,而此时m_data将是一个空指针,在后续使用中容易导致程序崩溃。
代码如下:
String& String::operator=(const String &another)
{
if(&another!=this)
{
String strTmp(another);
char *tmp=strTmp.m_data;
StrTmp.m_data=m_data;
m_data=tmp;
}
return *this;
}
补充:在笔试面试过程中,也经常考察对整个string类的编写,主要包括构造函数,析构函数,拷贝构造函数,拷贝赋值运算符等,需理解牢记。
代码如下:
class String
{
public:
String (const char* str=NULL);//普通构造函数
String(const String &another);//拷贝构造函数 注意形参要是常量引用类型
~String();//析构函数
String & operator=(const String &another);//拷贝赋值操作符 形参要是常量引用类型,返回引用类型
private:
char *m_data;
};
String::String(const char*str)
{
if(NULL==str)
{
m_data=new char;
m_data='\0';//此处注意
}
else
{
m_data=new char[strlen(str)+1];
strcpy(m_data,str);
}
}
String::~String()
{
delete [] m_data;
m_data=NULL;
}
String::String (const String &another)
{
m_data=new char[strlen(another.m_data)+1];
strcpy(m_data,another.m_data);
}
String& String::operator=(const String &another)//注意返回类型写在前面
{
if(&another==this)
{
return *this;
}
delete [] m_data;
m_data=NULL;
m_data=new char[strlen(another.m_data)+1];
strcpy(m_data,another.m_data);
return *this;
}