运算符重载
在C++中,同一个类型或运算符在不同的类中有不同的含义或实施不同的运算,这也是面向对象的多态性
- 运算符重载是使一个运算符作用于不同类型的数据时具有不同的行为
- 实质上,是将运算对象转化为运算函数的实参,并根据实参的类型来确定重载的运算函数
- 运算符重载和类型重载是多态的另外两种表现形式
实现
-
定义一个重载运算符的函数,在需要执行被重载的运算符时,系统自动调用该函数,以实现相应的运算。
-
即,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。
-
在定义了重载运算符的函数之后,可以说“函数operator+重载了运算符+”
-
两个整数的相交可以理解为调用了以下函数
int operator+(int a, int b) { return a+b; }
-
-
-
格式:
函数类型 operator 运算符名称(形参列表) { }
- 函数原型,例:
Complex operator+(Complex& c1, Complex& c2);
- 函数原型,例:
ATTENTION
- 只能重载C++中已存在的运算符,不能臆造新的运算符
- 以下运算符不能重载
- 类属关系运算符
.
- 作用域分辨符
::
- 成员指针运算符
*
-
sizeof
运算符 - 三目运算符
? :
- 类属关系运算符
- 重载之后的运算符的操作数个数、原有的优先级、结合性和语法结构不改变
- 单目运算符只能重载为单目运算符,三目运算符只能重载为三目运算符
- 重载运算符的函数不能有默认参数
- 运算符重载后的功能应当与原有功能相类似
- 必须和用户定义的自定义类型的对象一起使用
- 其参数至少应该有一个是类对象(或类对象的引用)
- 重载运算符的含义必须清楚,不能有二义性。用于类对象的运算符一般必须重载,但运算符
=
和&
不必用户重载
重载形式
-
重载为类的成员函数
-
在类中用关键字
operator
定义一个成员函数 -
一般格式
<类型> <类名>::operator<重载的运算符>(形参表) { }
<类型>:运算符重载函数的返回类型
<类名>:成员函数所属类的类名
operator<重载的运算符>:重载函数名 -
双目运算:
oprd1 B oprd2
- 把
B
重载为oprd1
所属类的成员函数,只有一个形参,形参的类型是oprd2
所属类 - 表达式
oprd1+oprd2
就相当于函数调用oprd1.operator+(oprd2)
- 把
-
单目运算:
U oprd
- 把
U
重载为oprd
所属类的成员函数,没有形参 -
++oprd
相当于oprd.operator++()
- 把
-
后置单目运算:
oprd V
- 把
V
重载为oprd
所属类的成员函数,带有一个整形形参-
oprd--
相当于oprd.operator--(0)
-
- 把
-
Example 1. 复数的加减运算符重载
#include <iostream> using namespace std; class Complex { private: double real; double image; public: Complex(double r = 0, double i = 0) { real = r; image = i; } void show() { cout << "Complex number: " << real; if (image > 0) { cout << "+" << image << "i" << endl; } else if (image < 0) { cout << image << "i" << endl; } } Complex Add(const Complex& c) { Complex t; t.real = this->real + c.real; t.image = this->image + c.image; return t; } Complex operator+(const Complex& c) { Complex t; t.real = this->real + c.real; t.image = this->image + c.image; return t; } Complex operator-(const Complex& c) { Complex t; t.real = this->real - c.real; t.image = this->image - c.image; return t; } Complex& operator+=(const Complex& c) { real += c.real; image += c.image; return *this; } Complex& operator=(const Complex& other) { if (this == &other) return *this; this->real = other.real; this->image = other.image; return *this; } }; int main() { Complex c1(12, 35), c2(20, 46), c3, c4, c5, c6; c1.show(); c2.show(); c3 = c1.Add(c2); c3.show(); c4 = c1 + c2; c4.show(); c2 += c1; c2.show(); c5 = c1 - c2; c5.show(); return 0; } /* Complex number: 12+35i Complex number: 20+46i Complex number: 32+81i Complex number: 32+81i Complex number: 32+81i Complex number: -20-46i */
-
Example 2. 单目运算符重载
#include <iostream> using namespace std; class Time { private: int hour, minute, second; public: Time(int h = 0, int m = 0, int s = 0) :hour(h), minute(m), second(s) {} void show() { cout << hour << ":" << minute << ":" << second << endl; } Time& operator++() { second++; if (second == 60) { second = 0; minute++; if (minute == 60) { minute = 0; hour++; if (hour == 60) hour = 0; } } return *this; } Time& operator++(int) { Time temp = *this; second++; if (second == 60) { second = 0; minute++; if (minute == 60) { minute = 0; hour++; if (hour == 60) hour = 0; } } return temp; //后置++,返回原值 } Time& operator=(const Time& other) { if (this == &other) return *this; this->hour = other.hour; this->minute = other.minute; this->second = other.second; return *this; } }; int main() { Time t1(10, 25, 52), t2, t3; t1.show(); t2 = ++t1; t1.show(); t2.show(); t3 = t1++; t3.show(); t1.show(); } /* 10:25:52 10:25:53 10:25:53 10:25:53 10:25:54 */
-