1. 判断两个对象相等
class Date {
public:
Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date(const Date& d) {
_year = d._year;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1(2019, 4, 1);
Date d2(2019, 3, 31);
cout << (d1 == d2) << endl; // 能否常规的用 == 进行判断两对象相等?
system("pause");
return 0;
}
然而,单纯的使用系统自带的''==''来进行来两个对象的相等判断,是无法通过编译的。
在此我们可以采用创建一个判断相等函数用以解决两个对象的相等判断:
class Date {
public:
Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date(const Date& d) {
_year = d._year;
}
bool isEqual(const Date& d1) {
return _year == d1._year
&& _month == d1._month
&& _day == d1._day;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1(2019, 4, 1);
Date d2(2019, 3, 31);
//cout << (d1 == d2) << endl;
cout << d1.isEqual(d2) << endl;
system("pause");
return 0;
}
但是,采用函数定义来解决问题时,函数名能否“见名知意”是很关键的,在大多数情况之下,函数名会导致代码可读性不强。而运算符重载将''==''通过重载实现支持Date类型的相等判断,即可以大大提高代码的可读性。
2. 运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
注意:
1) 不能通过连接其他符号来创建新的操作符:比如operator@ ,对于原来没有定义的运算符自己不允许创造出新的运算符。
2) 重载操作符必须有一个类类型或者枚举类型的操作数 。
3) 用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义 ,内置类型语言已经定义了其逻辑功能,不能对其做改变。运算符重载相当于在自定义类型中定义另一种逻辑。
4) 作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的
5) 操作符有一个默认的形参this,限定为第一个形参
6) .*(成员访问运算符) 、::(作用域限定运算符) 、sizeof(计算字节大小运算符) 、?:(三目运算符) 、. (点号运算符)注意以上5个运算符不能重载。这个经常在笔试选择题中出现。
全局函数(非成员函数)的''==''的运算符重载实现:
class Date {
public:
Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date(const Date& d) {
_year = d._year;
}
public:
// 这里会发现运算符重载成全局的就需要成员变量是共有的,那么问题来了,封装性如何保证?
// 这里其实可以用我们后面学习的友元解决,或者干脆重载成成员函数。
int _year;
int _month;
int _day;
};
bool operator==(Date& d1, Date& d2) { // 对 == 进行运算符重载
return d2._year == d1._year
&& d2._month == d1._month
&& d2._day == d1._day;
}
int main() {
Date d1(2019, 4, 1);
Date d2(2019, 3, 31);
cout << (d1 == d2) << endl;
system("pause");
return 0;
}
可以来比较一下代码的可读性:
cout << (d1 == d2) << endl; // 运算符重载
cout << d1.isEqual(d2) << endl; // 函数调用
还是进行运算符重载后的''==''既能够完成对象之间的相等判断,又能够“显然”的了解其功能作用。
成员函数的''==''的运算符重载实现:
当将其写为成员函数时,所对应的函数参数会少一个。还记得this指针吗?成员函数内部的第一个参数均为this指针,其指向当前调用该函数对象的地址。
class Date {
public:
Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
Date(const Date& d) {
_year = d._year;
}
bool operator==(Date& d1) { // 成员函数 == 运算符重载
return this->_year == d1._year // this在此写不写无所谓
&& _month == d1._month
&& _day == d1._day;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1(2019, 4, 1);
Date d2(2019, 3, 31);
cout << (d1 == d2) << endl; // 直接写法
cout << d1.operator==(d2) << endl; // 编译器执行时
system("pause");
return 0;
}
这是定义为成员函数的写法。在函数内部this指针进行的解引用不非要显式写出,在后的函数调用有直接写法、编译器执行时两种写法,均能够正常调用,只不过直接写法更适合我们直观理解,而实际上编译器是用后者进行调用处理的。
两者的区别:
1)全局函数运算符需要几个参数就得输入几个参数。
2)成员函数运算符个数时所需参数再减1,其中第一个参数被this指针所代替。