C++ 运算符重载(Operator Overloading)
运算符重载写法
类似与定义函数一样,只是把函数名变成operator 运算符
。
例:
Time operator*(double mult, const Time & t) {
Time result;
long totalminutes = t.hours * mult * 60 + t.minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
1. 类中运算符重载
通过在类中定义成员函数实现:
class Time{
private:
int hours;
int minutes;
public:
Time(){hours = 0, minutes = 0;};
Time(int h, int m = 0): hours(h), minutes(m){};
Time operator*(double mult) const; // 别忘加 const
void show() const {cout << hours << ":" << minutes << endl;};
};
Time Time::operator*(double mult) const{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
上面程序中实现的运算符重载,可以做如下使用:
Time A(1, 2);
Time B = A * 2;
B.show()// 2:4
注意:以上不可以写成: B = 2 * A;
,这样写是错误的,无法通过编译。
因为B = A * 2;
被编译器转换成了成员函数调用:B = A.operator*(2)
;而B = 2 * A
中的2
不是对象,编译器无法使用类成员函数进行转换。如果要解决以上出现问题,就要使用接下要介绍的友元函数重载。
2. 友元函数重载
通过在类中声明Time operator*(double mult, const Time &t)
是友元函数:
注意:
- 虽然
operator*()
在类中声明了,但它不是成员函数,因此不能使用成员函数运算符调用。- 虽然
operator*()
不是成员函数,但是它与成员函数的访问权限相同。
class Time{
private:
int hours;
int minutes;
public:
Time(){hours = 0, minutes = 0;};
Time(int h, int m = 0): hours(h), minutes(m){};
friend Time operator*(double mult, const Time &t);
void show() const {cout << hours << ":" << minutes << endl;};
};
Time operator*(double mult, const Time & t) {
Time result;
long totalminutes = t.hours * mult * 60 + t.minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
上面程序中实现的运算符重载,可以做如下使用:
Time A(1, 2);
Time B = 2 * A;
B.show(); //2:4
注意:以上不可以写成: B = A * 2;
,这样也不行。如果既要用B = A * 2
和B = 2 * A
,可以把类中运算符重载和友元重载结合使用。
因为B = 2 * A;
被编译器转换成了:B = operator*(2, A)
, 从而调用刚刚定义的非成员友元函数。
B = A * 2
和B = 2 * A
一起使用:
#include <iostream>
using namespace std;
class Time{
private:
int hours;
int minutes;
public:
Time(){hours = 0, minutes = 0;};
Time(int h, int m = 0): hours(h), minutes(m){};
friend Time operator*(double mult, const Time &t);
Time operator*(double mult) const;
void show() const {cout << hours << ":" << minutes << endl;};
};
Time Time::operator*(double mult) const{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
Time operator*(double mult, const Time & t) {
Time result;
long totalminutes = t.hours * mult * 60 + t.minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
int main() {
Time A(1, 2);
Time B = 2 * A;
B.show(); // 2:4
Time C = A * 3;
C.show(); // 3:6
return 0;
}
重载 <<
运算符
第1种方法
friend void operator<<(ostream &os, const Time &t); // 先在类中声明;
void operator<<(ostream &os, const Time &t) {
os << t.hours << " hours, " << t.minutes << " minutes";
}
// 使用
trip(4, 23);
cout << trip;// 4 hours, 23 minutes
注意:通过这种重载方法之后,cout <<
不能像平时那样正常使用了,比如cout << trip << "test1234" << endl
这样写就会报错。接下来介绍第2种方法来解决此问题。
第2种方法
friend ostream& operator<<(ostream &os, const Time &t); // 先在类中声明;
ostream& operator<<(ostream &os, const Time &t) {
os << t.hours << " hours, " << t.minutes << " minutes\n";
return os;
}
// 使用
trip(4, 23);
cout << trip << " test1234" << endl;// 4 hours, 23 minutes test1234
附——友元声明
1. 友元函数
class A{
private:
int n;
public:
friend void test(int x, A &a);
};
void test(int x, A &a) {
a.n = x;
cout << "num: " << a.n << endl;
}
2. 友元类
class A{
private:
int n;
public:
friend class B;
};
class B{
private:
int t;
public:
void test(int x, A &a) {
a.n = x;
cout << "num: " << a.n << endl;
}
};
3. 友元类成员函数
class A; // 要先定义class A
class B{
private:
int t;
public:
void test(int x, A &a); // 在外部实现,不能在内部实现
};
class A{
private:
int n;
public:
friend void B::test(int x, A &a);
};
void B::test(int x, A &a) {
a.n = x;
cout << "num: " << a.n << endl;
}