##赋值运算操作符
为如下类型添加赋值运算。
class MyString
{
public:
MyString(char* pData = NULL);
MyString(const MyString str);
~MyString();
private:
char* m_pData;
}完整地考虑如下四个方面:
- 证同测试
- 常量引用参数
- 是否释放自身已有的内存
- 返回值类型
考虑了以上注意事项后可以写出如下代码:
MyString& MyString::opertor =(const MyString &str)
{
if(this == &str)
{
return *this;
}
delete []m_pData;
m_pData = NULL;
m_pData = new char[strlen(str.m_pData)+1];
strcpy(m_pData,str.m_pData);
return *this;
}然而上述代码却不具备异常安全,比如new操作失败,则m_pData指向了NULL。
考虑异常安全后,可以写出如下代码:
MyString& MyString::opertor =(const MyString &str)
{
if(this == &str)
{
//Temp obj
MyString temp(str);
//point to new data
char* pTemp = temp.m_pData;
//edit temp.m_pData to original address
temp.m_pData = m_pData;
//this.m_pData point to new data
m_pData = pTemp;
}
//here calls the destructor
//means delete temp object
//thus temp.m_pData
//therefore delete the original m_pData
return *this;
}其实自身赋值是一个极少发生的事件,所以在代码里每次都做证同测试显得不那么高效,所以:
MyString& MyString::opertor =(const MyString &str)
{
MyString temp(str);
char* pTemp = temp.m_pData;
temp.m_pData = m_pData;
m_pData = pTemp;
return *this;
}
/*
When leaving this scope calls the destructor
means delete temp object
thus temp.m_pData
therefore delete the original m_pData
*/而上述的代码其实仍然满足证同的功能。