类中赋值运算符重载函数
声明一个字符串类,为这个类型添加赋值运算符
class MyString { public: //构造函数 MyString(char* pData = NULL); //构造函数 MyString(const MyString& str); //析构函数 ~MyString(void); //赋值运算符 MyString& operator=(const MyString& str); private: char* m_pData; };
该字符串类中只有两个构造函数,一个析构,一个赋值运算符的重载,着重来说赋值运算符的重载,重载之前将构造函数和析构函数实现了
MyString::MyString(char *pData) { if(pData == NULL) { m_pData = new char[1]; m_pData[0] = '\0'; } else { m_pData = new char[strlen(pData) + 1]; strcpy(m_pData, pData); } } MyString::MyString(const MyString &str) { m_pData = new char[strlen(str.m_pData) + 1]; strcpy(m_pData, str.m_pData); } MyString::~MyString() { delete[] m_pData; }
S1 = S2 ,S1传给第一个参数,S2传给第二个参数,赋值自然顺理成章,以下是代码:
MyString& MyString::operator=(const MyString& str) { if (this != &str) //如果相等,即就是给自身赋值,直接返回*this; { delete[]m_pData; //释放原实例中 m_pData的内存 m_pData = NULL; m_pData = new char[strlen(str.m_pData) + 1]; strcpy(m_pData, str.m_pData); //重新申请空间并完成拷贝 } return *this; }但是,以上代码书上说,还存在安全问题,说是,上例的赋值运算重载中释放了原有的实例对象内存,而去重新申请了内存,但是,一旦申请内存失败,也就是说new char 抛出了异常,m_pData将是一个空指针,问题就是一大堆,怎么办呢?一种方法是:先new 一块新内存,在delete释放已有的内存,这样,只有在内存分配成功之后才会释放原有内容,分配失败,原来的实例也不会被修改;
MyString& MyString::operator=(const MyString& str) { if (this != &str) { char* tmp = new char[strlen(str.m_pData) + 1]; if (tmp != nullptr) { delete[]m_pData; m_pData = NULL; m_pData = tmp; strcpy(m_pData, str.m_pData); } } return *this; }还有更好的写法:
MyString& MyString::operator=(const MyString& str) { if (this != &str) { MyString tmp(str); swap(m_pData,tmp.m_pData); //库中交换函数 swap(); } return *this; }
还有大神是这样写的;
String& operator=(String rhs) // 传值 { swap(rhs); return *this; }
拙见,欢迎纠正;
good