题目
如下为类CMyString的声明,请为该类型添加赋值运算符函数。
1 class CMyString { 2 public: 3 CMyString (char * pData = NULL); 4 CMyString (const CMyString & str); 5 ~CMyString (void); 6 7 private: 8 char * m_pData; 9 };
错解
1 class CMyString { 2 public: 3 CMyString (char * pData = NULL); 4 CMyString (const CMyString & str); 5 ~CMyString (void); 6 7 void operator =(const CMyString & C) { 8 this->m_pData = C->m_pData; 9 } 10 private: 11 char * m_pData; 12 };
分析
1. 赋值运算符函数的返回值类型应该是该类型自身的引用,如此方能连续赋值。错解中返回了void,无法实现连续赋值。
2. 复制函数也好,重载赋值运算符函数也好,指针都不能直接赋予,否则两个对象指向同一片内存,自然会乱套。正确的解法应当先释放空间,然后再将指针指向的内容拷贝复制到另一个指针所指向的区域。
3. 在满足2的同时,我们在赋值的时候还应当判断赋值和被赋值的对象是不是同一个对象,否则一旦释放了对象,数据就全丢失了。
正解
1 class CMyString { 2 public: 3 CMyString (char * pData = NULL); 4 CMyString (const CMyString & str); 5 ~CMyString (void); 6 7 CMyString & operator =(const CMyString & str) { 8 9 // 判断赋值与被赋值对象是否同一个对象 是的话直接返回*this 10 if (this == &str) { 11 return *this; 12 } 13 14 // 清空指针指向的空间 15 delete []m_pData; 16 m_pData = NULL; 17 18 // 拷贝指针指向的内容 19 m_pData = new char[strlen(C.m_pData)+1]; 20 strcpy(m_pData, C.m_pData); 21 22 // 返回引用 23 return *this; 24 } 25 private: 26 char * m_pData; 27 };
待改进的地方
对于C++来说,内存的控制是至关重要的。如果能够考虑到内存泄漏这个方面,代码无疑更加优秀。
对于上面的代码,设想如果new失败了,则p_mData将会指向一个空的指针,同时抛出异常。这样就让操作数里的数据丢失了。
因此,要先new,再delete,代码略。
小结
在C++的面试题目中,除了关于语言的机制外,内存( 指针 )管理非常值得注意!!!