对于定义一个赋值运算符函数时,需要注意一下几点:
(1)函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值
(2)传入的参数声明为常量引用,可以提高代码效率,同时赋值运算函数内不会改变传入的实例状态
(3)一定要记得释放实例自身已有的内存,否则程序容易出现内存泄露
(4)注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可。
代码示例如下:
#include<iostream>
#include<string>
using namespace std;
class CMyString
{
public:
CMyString(char* pData = NULL);
CMyString(const CMyString& str);
~CMyString(void);
//声明返回值的类型为引用,才可以允许连续赋值
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] = '\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;
m_pData = new char[strlen(str.m_pData)+1];
strcpy(m_pData,str.m_pData);
return *this;
}
void CMyString::Print()
{
cout<<m_pData<<endl;
}
void test1()//普通赋值
{
cout<<"test1() begins:"<<endl;
char *text = "hello world";
CMyString str1(text);
CMyString str2;
str2 = str1;
cout<<"The expected result is: "<<text<<endl;
cout<<"the actual result is: "<<endl;
str2.Print();
cout<<endl;
}
void test2()//自身赋值
{
cout<<"test2() begins:"<<endl;
char *text = "hello world";
CMyString str1(text);
str1 = str1;
cout<<"The expected result is: "<<text<<endl;
cout<<"the actual result is: "<<endl;
str1.Print();
cout<<endl;
}
void test3()//连续赋值
{
cout<<"test3() begins: "<<endl;
char *text = "hello world";
CMyString str1(text);
CMyString str2,str3;
str3 = str2 = str1;
cout<<"The expected result is: "<<text<<endl;
cout<<"the actual result is: "<<endl;
str2.Print();
cout<<endl;
cout<<"The expected result is: "<<text<<endl;
cout<<"the actual result is: "<<endl;
str3.Print();
cout<<endl;
}
int main()
{
test1();
test2();
test3();
return 0;
}
总结:运算符函数、常量引用的使用。
何时使用赋值操作符:
(1)将已有的对象赋给另一个对象时,将使用重载的赋值操作符;
初始化时并不一定使用赋值操作符,一般使用复制构造函数。但是使用复制构造函数创建一个临时对象,然后通过赋值将临时对象的值复制到新对象中。
赋值操作符的功能:
赋值操作符的隐式实现也对成员进行逐个复制。如果成员本身是类对象,则程序将使用为这个类定义的赋值操作符来复制该成员,但静态数据成员不受影响。