探寻C++类——重载赋值操作符(operator=)
已经忙碌一个多月,现在才想起来要更博了。今天在写课堂实验时,一题为:
编写一个程序:输入几个学生的姓名、英语和计算机成绩,然后按照总分从高到低排序。要求定义一个Student类,并用友元函数实现排序。
开始看到这题觉得还是挺简单的,其中排序是常见的冒泡排序。众所周知,冒泡排序中,需要建立一个缓存变量来交换变量。而在此例中,需要交换的是类对象,那么解决方法则有两种:
第一种方法是使用一个自定义的equal函数
void equal(Student &a,Student &b) { strcpy(a.name,b.name); // require include <string> a. englishScore = b. englishScore; a. computerScore = b. computerScore; a. totalScore = b. totalScore; }
第二种方法则是使用运算符重载,这里则需要重载赋值操作符(operator=)
刚使用重载赋值操作符时,在函数中创建新对象,处理完后返回新对象的引用,结果发现这样做是十分危险而且是错误的。
查阅CSDN和书籍,对于赋值操作符=的重载有如下说明:
string& operator=(const string&);// s1=s2 string& operator=(const char *);// s1="str" string& operator=(char);// s1='c'
需要注意的是:无论形参为何种类型,赋值操作符必须定义为成员函数,且必须返回对*this的引用。
因而得到以下函数体:
MyClass& MyClass::operator=(const MyClass &T) { // do something }
但上述函数体仍不完善,例如a=a时会出现什么情况?还有需要考虑性能问题。
为了防止自身赋值,需要判断一下:
MyClass& MyClass::operator=(const MyClass &T) { if (this == &T) return *this; // do something return *this; }
结合题目,可写出如下重载函数:
Student& Student::operator=(const Student &T) { if (this == &T) return *this; strcpy(name, T.name); // require include <string> englishScore = T.englishScore; computerScore = T.computerScore; totalScore = T.totalScore; return *this; }
通过实验,发现使用重载操作符会比使用equal函数更方便,从而整理出重载操作符的一些规则供以后学习使用。
1、除了函数调用操作符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数数目相同。
2、形参值要为const类型。
3、返回一个引用,以便于实现a=b=c。
4、&&、&、||和,等操作符最好不要重载。
5、类一般都需重载输入/输出操作数,IO操作符必须为非成员符,所以类常将其设为友元。
6、作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数。
7、重载操作符必须具有至少一个类类型的操作数。
发表回复