剑指Offer----面试题一:为类添加赋值运算符函数

来源:互联网 发布:java接口的定义 编辑:程序博客网 时间:2024/05/17 04:50

转载请注明出处<http://blog.csdn.net/qianqin_2014/article/details/51446040>


题目:

如下类型CMyString的声明,请为该类型添加赋值运算符函数

class CMyString{public:CMyString(char *pData = NULL);CMyString(const CMyString & str);~CMyString(void);private:char *pData;};

思路:

  • 返回类型必须是引用类型,以便连续赋值
  • 形参类型为常量引用类型,避免传参时调用复制构造函数,且我们不改变实例的状态
  • 是否释放实例自己已有的内存。如果在分配新内存之前忘记释放原有内存,将会产生内存泄漏问题
  • 判断传入的参数和已有的示例是否相同,相同的话就不用复制了(释放掉内存,导致内存被破坏),否则,深度复制
CMyString& CMyString::operator=(const CMyString &str){if (this == &str)return *this;delete[] pData;pData = nullptr;pData = new char(sizeof(str.pData));//pData = new char(strlen(str.pData) + 1);strcpy(pData, str.pData);return *this;}

考虑异常


如果内存不足将导致new char抛出一个bad_alloc异常,此时的pData指针将会是一个空指针,这样会导致程序的崩溃!处理此问题有两种方法:
一:先分配内存,只有新的内存分配成功之后再释放掉原有的内存,这样能保证内存分配失败后原有的实例不会被改变。
二:先创建一个临时实例,再交换临时实例和原来的实例。(这种方法更好)
CMyString& CMyString::operator=(const CMyString &str){if (this != &str){CMyString strTemp(str);char * temp = strTemp.pData;strTemp.pData = pData;pData = temp;}return *this;}

分析:

strTemp是一个局部变量,将自身的指针和原有实例的指针交换,当局部变量strTemp到达if外边的时候,就会调用自身的析构函数,释放掉原有原有指针指向的内存空间。注意:如果内存不足,(我们在复制构造函数里使用new分配内存)在CMyString的时候将会抛出一个异常,以后的函数将不会被执行,也就不会修改原来的状态。

源代码:

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstring>//包含strcpy,strlenclass CMyString{public:CMyString(char *pData1 = NULL);CMyString(const CMyString & str);CMyString & operator=(const CMyString & str);~CMyString(void);const void print() const;private:char *pData;};CMyString::CMyString(char *pData1)//定义时不再需要指定默认参数{if (pData1 == NULL){//注意这种处理方式pData1 = new char[1];pData1 = '\0';}else{pData = new char[strlen(pData1) + 1];strcpy(pData, pData1);}}CMyString::CMyString(const CMyString &str){pData = new char[strlen(str.pData) + 1];strcpy(pData, str.pData);}CMyString& CMyString::operator=(const CMyString &str){if (this != &str){CMyString strTemp(str);char * temp = strTemp.pData;strTemp.pData = pData;pData = temp;}return *this;}CMyString::~CMyString(void){delete[] pData;}const void CMyString::print() const{std::cout << pData << std::endl;}int main(){std::cout << "========testing1:复制构造函数=========" << std::endl;CMyString s1("C++");CMyString s2(s1);std::cout << "s1.pData = ";s1.print();std::cout << "s2.pData = ";s2.print();std::cout << std::endl;std::cout << "========testing2:赋值构造函数=========" << std::endl;CMyString s3;s3 = s1;std::cout << "s3.pData = ";s3.print();std::cout << std::endl;std::cout << "========testing2:连续使用赋值构造函数=========" << std::endl;CMyString s4("Offer");CMyString s5, s6;s5 = s6 = s4;std::cout << "s5.pData = ";s5.print();std::cout << "s6.pData = ";s6.print();std::cout << std::endl;system("pause");return 0;}

测试结果:
========testing1:复制构造函数=========s1.pData = C++s2.pData = C++========testing2:赋值构造函数=========s3.pData = C++========testing2:连续使用赋值构造函数=========s5.pData = Offers6.pData = Offer请按任意键继续. . .


转载请注明出处<http://blog.csdn.net/qianqin_2014/article/details/51446040>

0 0
原创粉丝点击