#include <iostream>
#include <string>
using namespace std;

class CMyString
{
public:

CMyString(char *pData=NULL);//构造函数
CMyString(const CMyString &str);//复制构造函数
CMyString& operator=(const CMyString &str);

~CMyString(void);//析构函数

void Print();
private:
char *m_pData;
};

void CMyString::Print()
{
cout<<m_pData<<endl;
}

CMyString::CMyString(char *pData)
{
if(pData==NULL)
{
m_pData=new char[1];
m_pData[0]='\0';
}
else
{
int len=strlen(pData);
m_pData=new char[len+1];
strcpy(m_pData,pData);
}

}

CMyString::CMyString(const CMyString &str)
{
int len=strlen(str.m_pData);
m_pData=new char[len+1];
strcpy(m_pData,str.m_pData);
}


CMyString& CMyString::operator=(const CMyString &str)
{
if(this==&str)//判断传入的参数和当前实例是不是同一个实例
return *this;

delete [] m_pData;//释放实例自身已有的内存
m_pData=new char[strlen(str.m_pData)+1];
strcpy(m_pData,str.m_pData);

return *this;
}

CMyString::~CMyString()
{
delete[] m_pData;
}

int _tmain(int argc, _TCHAR* argv[])
{
char *test="Hello Offer!";
char *test2="Hello MayDay!"; CMyString str1; CMyString str2(test1);
CMyString str3(test2); cout
<<"str3赋值给str2,str2赋值给str1:"<<endl; str1=str2=str3; str1.Print(); str2.Print(); cout<<"str2赋值给自己"<<endl; str2=str2; str2.Print(); return 0; }

重载赋值操作符时应注意:

1、是否把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)。【只有返回一个引用,才可以允许连续赋值】测试:str1=str2=str3,是否通过。

2、是否把传入的参数的类型声明为常亮引用。【如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,(无谓的消耗)】把参数声明为引用可以避免这样无谓的消耗,提高代码的效率。【不会改变传入的实例状态,引用参数加上const关键字】。

3、是否释放实例自身已有的内存。【在分配新内存之前要释放自身已有的空间,否则,内存泄露】

4、是否判断传入的参数和当前的实例(*this)是不是同一个实例。【若不进行判断,释放了自身的内存的同时,传入的参数内存也被释放了,就找不到需要赋值的内容了】