探寻C++类——重载赋值操作符(operator=)

目录 C/C++

已经忙碌一个多月,现在才想起来要更博了。今天在写课堂实验时,一题为:

编写一个程序:输入几个学生的姓名、英语和计算机成绩,然后按照总分从高到低排序。要求定义一个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、重载操作符必须具有至少一个类类型的操作数。

暂无评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据