题目描述:
如下为类型CMyString的声明,请为该类型添加赋值运算符函数。
题目分析:
定义一个赋值运算符函数,应注意以下几点:
1)返回值的类型应为该实力自身的引用(即*this)。返回引用,才可以连续赋值。
2)传入的参数类型声明为const常量引用。理由有两点:一是在赋值运算符函数内不会改变传入的实例;二是如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,把参数声明为引用可以避免该无谓消耗,能提高代码效率。
3)一定要释放实例自身已有的内存。如果忘记在分配新内存之前释放自身已有空间,程序将出现内存泄漏。
4)记得判断传入的参数和当前实例(*this)是否是同一个实例。如果是同一个,直接返回即可,不用赋值。如果事先不判断,当*this和传入的参数是同一个实例时,一旦释放了自身的内存,传入的参数的内存也就释放掉了,因此再也找不到需要赋值的内容了。
代码:
#include <iostream>
#include <string>
using namespace std;
class CMyString {
public:
CMyString(char * pData = NULL);
CMyString(const CMyString& str);
~CMyString(void);
//返回类型为引用,才可以连续赋值;传入的参数设为const,减少复制构造函数的调用。
CMyString& operator = (const CMyString& str);
void Print();
private:
char * m_pData;
};
CMyString :: CMyString(char * pData) {
if(pData == NULL) {
m_pData = new char[1];
m_pData = '\0';
}
else {
int length = strlen(pData);
m_pData = new char[length + 1];
strcpy(m_pData, pData);
}
}
CMyString :: ~CMyString(){
delete []m_pData;
}
CMyString& CMyString :: operator= (const CMyString& str) {
if(this == &str)
return *this;
delete []m_pData;
m_pData = NULL;
int length = strlen(str.m_pData);
m_pData = new char[length + 1];
strcpy(m_pData, str.m_pData);
return *this;
}
void CMyString::Print(){
cout << m_pData << endl;
}
void test1() { //普通赋值
cout << "****test1:**** " << endl;
CMyString str1("hello world");
CMyString str2;
str2 = str1;
cout << "赋值后应该是:" <<endl;;
str1.Print();
cout << "赋值后实际是:" <<endl;
str2.Print();
}
void test2() { //自身赋值
cout << "****test2: ****" << endl;
char *text = "my name is lmm";
CMyString str1(text);
str1 = str1;
cout << "赋值后应该是:" <<endl;
cout << text << endl;
cout << "赋值后实际是:" << endl;
str1.Print();
}
void test3() { //连续赋值
cout << "****test3: ****" << endl;
CMyString str1("lucky dog");
CMyString str2, str3;
str3 = str2 = str1;
cout << "连续赋值后应该是:" ;
str1.Print();
cout << "连续赋值后str2 是:" <<endl;
str2.Print();
cout << "连续赋值后str3 是:" <<endl;
str2.Print();
}
int main() {
test1();
test2();
test3();
return 0;
}