1.运算符重载概念
多态性是C++的一大性质,多态性同样体现在c++的数据运算之中。
运算符能将一个或多个数据进行计算,其是有运算过程被省略的,在某些情况下,原运算符能进行的运算不在能运算所需数据时,就需要我们自己去定义运算过程来运算对应数据,这就是运算符重载。
比如:“+”无法计算复数,就可以重载运算过程来计算复数。
可重载运算符:
分类 | 具体 |
---|---|
双目算术运算符 | +(加),-(减),*(乘),/(除),%(取模) |
关系运算符 | ==(等于),!=(不等于),<(小于),>(大于),<=(小于等于),>=(大于等于) |
逻辑运算符 | II(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | +(正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),–(自减) |
位运算符 | I(按位或),&(按位与),~(按位取反),^(按位异或),《<(左移),>》(右移) |
赋值运算符 | =(赋值),+=(加法赋值),-=(减法赋值),*=(乘法赋值),/=(除法赋值), %=(取模赋值), |
赋值运算符 | &=(按位与赋值), |=(按位或赋值),^=(按位异或赋值),<<=(左移赋值),>>=(右移赋值) |
空间申请与释放 | new(创建对象),delete(释放对象) |
其他运算符 | ()(函数调用),-》(成员访问),,(逗号),[](下标) |
不可重载运算符:
分类 | 具体 |
---|---|
成员访问运算符 | . |
成员指针访问运算符 | .*,->* |
域运算符 | :: |
长度运算符 | sizeof |
条件运算符 | ? : |
预处理运算符 | # |
- 双目运算符只能重载为双目运算符,单目运算符只能重载为单目运算符
- 除了new、delete外,任何运算符不能重载为静态函数。
- =、[]、()、->和所有的类型转换运算符只能作为成员函数重载,不能重载为友元函数
- 重载后运算符语义不会改变,包括优先级、结合性
2.重载运算符的两种形式
2.1说明为类的成员函数
<返回类型> operator <运算符> (<参数表>)
声明的类为新的数据类型,重载后的运算符用此数据类型做返回值,要计算的数据也要用此类型定义
因此运算符原运算功能还是保留的
例:重载运算符“+”使其可以计算复数
#include<iostream>
using namespace std;
class Complex {
public:
Complex(int a,int b) {
real = a;
imag = b;
}
Complex operator + (Complex &c2);//对于双目运算符,只需要一个参数,且这个参数代表第二个数据
void display();
private:
int real;
int imag;
};
Complex Complex :: operator + (Complex &c2) {
return Complex(this->real + c2.real, this->imag + c2.imag);//返回类型同样要为设定的类型
}
void Complex::display() {
cout << real << '+' << imag << 'i';
}
int main() {
Complex c1(3, 2), c2(2, 4), c3(0,0);
c3 = c1 + c2;
c3.display();
return 0;
}
- 因为类有this指针,所以类里可以存放一个数据。则对于双目运算符,参数表为第二个数据;对于单目运算符,参数表为第一个数据
- 新建的类相当于一个特定的数据类型,比如上例中类“Complex”视作“复数”这个数据类型
2.2说明为类的友元函数
friend <返回类型> operator <运算符> (<参数表>)
声明的类为新的数据类型,重载后的运算符用此数据类型做返回值,要计算的数据也要用此类型定义
因此运算符原运算功能还是保留的
#include<iostream>
using namespace std;
class Complex {
public:
Complex(int a,int b) {
real = a;
imag = b;
}
friend Complex operator + (Complex& c1,Complex &c2);//改变的地方:两个参数
void display();
private:
int real;
int imag;
};
Complex operator + (Complex& c1,Complex& c2) {//友元不需要域运算符指定
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
void Complex::display() {
cout << real << '+' << imag << 'i';
}
int main() {
Complex c1(3, 2), c2(2, 4), c3(0,0);
c3 = c1 + c2;
c3.display();
return 0;
}
- 相比于成员函数,友元函数没有this指针,即无法调用类的数据,所以作为双目运算符,两个数据都要出现;单目即要有一个参数
3.典型运算符的重载
3.1自增自减运算符的重载
++:自增运算符 –:自减运算符
对于++而言(–同理),格式为:
作为类的成员函数:
前缀运算:<返回类型> operator ++ ()
后缀运算:<返回类型> operator ++ ( int )
作为类的友元函数:
前缀运算:friend <返回类型> operator ++ ()
后缀运算:friend <返回类型> operator ++ (参数1, int )
int只是用于区别于前缀运算和后缀运算,可当作固定格式
自增自减的重载可以让其他格式的数据(比如类)也可以用上自增自减功能
3.2流运算符的重载
>>:流插入运算符 <<:流提取运算符
重载此运算符便于数据格式化的输入输出,例如:可以重载>>在结尾输出换行,以便不用手动换行
只能重载为非类成员函数,一般重载为友元函数
格式为:
friend istream& operator >> (istream& , <类名>&);
friend ostream& operator << (ostream&, <类名>);
3.3其他
-
除法运算符\可以重载为分数运算符
-
减法运算符-可以重载为负数运算符
-
重载下标运算符[]使其可以检测数组是否越界