重载:使用相同的名称定义函数,用参数个数或类型不同区分两个函数。
eg:int inform(int a,int b);
int inform(int a,int b,int c);
int inform(float a,int b);
代码根据不同的参数个数或类型区分调用哪一个函数。
表1 可以重载的运算符
+ | - | * | / | % | ^ | & |
| | ~ | ! | , | = | < | > |
<= | >= | ++ | ―― | << | >> | = = |
!= | && | || | += | -= | /= | *= |
%= | ^= | &= | |= | >>= | <<= | [] |
( ) | -> | ->* | new | delete | new[] | delete[] |
一.对运算符重载的理解
- 与普通函数对比,例如:4=1+3 可以看做是一个名为“+”的函数,参数是两个int型数,返回int型数,即 int +(int ,int );
- 在C++中每种基本数据类型都可以通过运算符进行相关计算,所以我们需要重载的是针对两个对象的运算的运算符;
eg:class Vector{.......};
Vector v1,v2;
v1+v2; v1/v2;
二.基本语法
在c++中,定义 重载运算符的函数 命名需要关键字operator后紧跟需要重载的运算符
eg: 重载“+” : operator +
运算符重载函数的参数取决于:
- 运算符的操作数个数 一元运算符 二元运算符
- 运算符函数 成员函数 全局函数
将运算符定义为成员函数时,调用成员函数的对象(this指向的对象)作为运输符的第一个操作数,若该运算符是一元运算符,则不需要提供参数。重载二元运算符时,将当前对象(this指向的对象)作为左操作数,需要提供一个参数作为右操作数。
#include<iostream>
using namespace std;
class MinInt {
char b;
public:
MinInt(char ch=0):b(ch){}
//构造函数,在构造对象时若用户输入一个char类型,则赋值给b;无则b默认为0;
//在类中重载,为成员函数,会自动调用该类的对象(this指向的对象)作为左运算符,函数中只需要写出右操作数的参数
MinInt operator-()const {
//const 表示不改变当前参数(左操作数)
//重载负号"-",为一元运算符,不需要参数做右操作数
cout << "MinTnt::operator-" << endl;
return MinInt(-b);// 返回类类型的新对象
}
MinInt operator+(const MinInt& rv)const {
//两个const分别表示右左两个操作数值不会改变
//重载"+",二元运算符 ,需要一个参数MinInt& rv作为右操作数;
cout << "MinInt::operator+" << endl;
return MinInt(b + rv.b);
}
MinInt& operator+=(const MinInt& rv) {
//重载复合赋值运算符"+="
cout << "MinInt operator+=" << endl;
b += rv.b;
return *this;//返回到this指向的对象(即第一个操作数)
}
};
int main() {
int v1 = 1, v2 = 2, v3 = 3;
v3 += v1 + v2;//不是类类型,调用系统内置的运算符
MinInt b1(10), b2(20), b3(30);
b3 += -b1 + b2;//调用类中重载后的运算符
}
将运算符函数定义为全局函数时,通常需要将其声明为类的友元。重载一元运输符需要提供一个类类型的参数,重载二元运算符需提供两个参数,至少有一个是类类型。
#include<iostream>
using namespace std;
class Integer {
long i;
Integer* This() { return this; }
public:
Integer(long ll = 0) :i(ll) {}//构造函数
friend const Integer& operator+(const Integer& a);//全局函数,友元声明
friend const Integer operator-(const Integer& a);
};
const Integer& operator+(const Integer& a) {
return a;
}
const Integer operator-(const Integer& a) {
return Integer(-a.i);
//返回新的integer型
}
赋值运算符“=”只能用成员函数重载
返回值的优化:
通过传值方式创建一个新对象时,使用语法 return Integer(left.i+right.i);
称为临时对象语法,含义是创建一个临时的Integer对象并返回它;
等同于: Integer temp(left.i +right.i);
return temp;
使用成员运算符的限制:左操作数必须是当前类的对象
表2 运算符重载建议
运算符 | 建议重载方式 |
一元运算符 | 成员函数 |
= [ ] ( ) -> ->* 类型转换 | 必须是成员函数 |
复合赋值运算符 | 成员函数 |
其他二元运算符 | 非成员函数 |
输入输出运算符<<和>> | 非成员函数 |