1.赋值操作符重载的原因赋值操作符是一个使用频率最高的操作之一通常情况下它的意义十分明确就是将两个同类型的变量的值从一端右端传到另一端左端。但在以下两种情况下需要对赋值操作符进行重载。一是赋值号两边的表达式类型不一样且无法进行类型转换。二是需要进行深拷贝。2. 赋值操作符重载的注意事项赋值操作符只能通过类的成员函数的形式重载。这就说明了如果要将用户自定义类型的值传递给基本数据类型的变量只能通过类型转换机制而不能利用重载来实现。当赋值号两边的表达式不一致的时候可能需要对赋值操作符进行重载见下面的例子。12345678910111213141516171819202122#include iostreamusingnamespacestd;classA{intnum;public:A(){num0;}A(inti){numi;}voidshow(){coutnumendl;}};intmain(intargc,char* argv[]){A a5;//符值符号两边的数据类型不一样这里表示创建新对象a.show();A a1;a11;//赋值号两边的数据类型不一样这是真正的赋值运算a1.show();}程序的输出结果是51在语句A a5中虽然用到了“”但它的语义是构造一个类A的对象a它等价于语句A a(5)所以该语句与赋值无关。而语句a11是一个真正的赋值语句变量a1的类型是A而常量1的类型是int由于可以通过类A的构造函数Aint将类型int转换成类型A实际上是以int为参数构造了一个类A的临时对象然后再完成赋值操作所以不必再对赋值操作符进行重载。3.深拷贝情况下对赋值操作符重载深拷贝是对赋值操作符进行重载的一个因素。那么什么是深拷贝呢简单的说深拷贝是在把一个类对象a拷贝到另一个对象b中去时如果对象a中包含非悬挂指针野指针那么要将a的指针所指区域的内容拷贝到b的相应指针所指的区域中去。进行深拷贝时一般对象a和b有相同的数据类型。如果在进行赋值时发生深拷贝就一定要对赋值操作符进行重载否则赋值运算符就会按赋值的常规语义进行成员变量之间传递数据而不发生深拷贝。考察如下例子。1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556#include iostreamusingnamespacestd;classStudent{char* name;intage;public:Student(){namenewchar[20];}Student(char* n,inta){namenewchar[20];if(name)strcpy(name,n);agea;}Student(constStudent s){namenewchar[20];*thiss;}voidshow(){coutThe students name is name;cout and of age ageendl;}~Student(){delete[] name;}Student operator(constStudent s){if(name)strcpy(name,s.name);ages.age;return*this;}};intmain(){Student s1(张三,18),s4(李四,20);Student s2;s1.show();s2s4;s2.show();Student s3s1;s3.show();return0;}程序的输出结果是The students name is 张三 and of age 18The students name is 李四 and of age 20The students name is 张三 and of age 18阅读以上程序注意如下几点。1由于在类Student中存在指针成员name所以当两个Student类成员之间赋值时必须使用深拷贝。执行s2s4;语句就是将s4对象赋值给s2其中将s4.name字符串的内容拷入s2.name就是对深拷贝的具体体现。2类的拷贝构造函数虽然与赋值操作符并不是一回事但通常可以在拷贝构造函数中利用赋值操作符重载以避免对两个对象之间传递数据的重复解释。3上面的程序直接使用strcpy(name,s.name);实现两个对象的字符串成员的数据传递。这是一种简化的做法存在很多隐患。比如如果源字符串的长度超过20个字符此程序会出现运行时错误。解决的办法是根据原字符串的长度重新分配目的字符串的长度再次之前还要释放目的字符串的空间。另外一个对象赋值给自己也会出现问题需要进行源对象和目的对象地址的比较再考虑赋不赋值。4由于深拷贝会涉及到内存的动态分配和释放等一些较为复杂的操作所以程序员在编写自定义类时要尽量避免深拷贝的出现。例如在上例中将成员变量name定义成string name就可以避免自己编写实现深拷贝的代码。实际的深拷贝工作是由string类来完成而string类是C标准库提供的我们可放心使用。5最赋值操作符进行重载时通常将操作符函数的返回值定义为赋值左操作数类型的引用。这是为了实现对赋值表达式的求值还有一个目的就是为了实现链式操作。