剑指offer 面试题1:赋值运算符函数
Q:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。
class CMyString { public: CMyString(char* pData = nullptr); CMyString(const CMyString& str); ~CMyString(void); private: char* m_pData; };
A:对于一个赋值运算符函数的注意点。1. 是否把返回值的类型声明为该类型的引用,且在函数结束前返回实例自身的引用(*this) 2. 是否把传入的参数的类型声明为常量引用 3. 是否释放实例自身已有的内存 4.判断传入的参数和当前的实例(*this)是不是同一个实例
初级程序员解法:
CMyString& CMyString::operator=(const CMyString& str) { if (this == &str) { return *this; } delete[]m_pData; m_pData = nullptr; m_pData = new char[strlen(str.m_pData) + 1]; strcpy(m_pData, str.m_pData); return *this; }
问题来了,如果此时内存不足,new char抛出异常,则m_pData将是一个空指针,这样非常容易导致程序崩溃,违背了异常安全性原则。可以先创建一个临时实例,在交换临时实例和原来的实例。
高级程序员解法:
CMyString& CMyString::operator=(const CMyString& str) { if (this != &str) { CMyString strTemp(str); char* pTemp = strTemp.m_pData; strTemp.m_pData = m_pData; m_pData = pTemp; } return *this; }