4.1 什么是运算符重载
对已有的运算符赋予多重含义。
将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。
编译系统对重载运算符的选择,遵循函数重载的选择原则。
4.2 运算符重载的方法
格式:
数据类型 operator 运算符(形参表){重载处理}
不能重载的运算符只有5个:
. 成员运算符
.* 成员指针运算符
:: 域运算符
sizeof 长度运算符
?: 条件运算符
举个栗子:重载+运算符
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(){
real = 0;
imag = 0;
}
Complex(double r, double i){
real = r;
imag = i;
}
Complex operator+(Complex &c2);
void display();
private:
double real;
double imag;
};
Complex Complex::operator+(Complex &c2){
Complex c;
c.real = real + c2.real;
c.imag = imag + c2.imag;
return c;
}
void Complex::display(){
cout << "(" << real << "," << imag << "i)" << endl;
}
int main(){
Complex c1(3, 4), c2(5, -10), c3;
c3 = c1 + c2;
cout << "c1+c2=";
c3.display();
return 0;
}
4.3 重载运算符的规则
(1)C ++只允许已有的部分运算符实施重载。
(2)不能重载的运算符有五个。
(3)重载不改变操作数的个数。
(4)重载不改变运算符的优先级。
(5)运算符重载函数不能带默认值参数。
(6)运算符重载函数必须与自定义类型的对象联合使用,其参数至少有一个类对象或类对象引用。
(7)C ++默认提供 = 和 & 运算符重载。
(8)运算符重载函数可以是类成员函数也可以是类的友元函数,还可以是普通函数。
(9)C++规定赋值运算符、下标运算符、函数调用运算符必须定义为类的成员函数;而输出流插入、输入流提取、类型转换运算符不能定义为类的成员函数。
4.4 运算符重载函数作为类成员函数和友元函数
#include <iostream>
using namespace std;
class Complex{
public:
Complex()
{
real = 0;
imag = 0;
}
Complex(double r)
{
real = r;
imag = 0;
}
Complex(double r, double i)
{
real = r;
imag = i;
}
friend Complex operator+(Complex &c1, Complex &c2);
void display();
private:
double real;
double imag;
};
Complex operator+(Complex &c1, Complex &c2){
return Complex(c1.real + c2.real, c1.imag + c2.imag);
} // 显式调用构造函数
void Complex::display(){
cout << "(" << real << "," << imag << "i)" << endl;
}
int main(){
Complex c1(3, 4), c2(5, -10), c3;
c3 = c1 + c2;
cout << "c1=";
c1.display();
cout << "c2=";
c2.display();
cout << "c1+c2=";
c3.display();
return 0;
}
+运算符重载为友元函数。
左侧必须是Complex类对象,程序中可以写成:c3 = c2 + n。不能写成:c3 = n + c2
4.5 重载双目运算符
#include <iostream>
#include <string.h>
using namespace std;
class String{
public:
String() { p = NULL; }
String(char *str);
friend bool operator>(String &string1, String &string2);
private:
char *p;
};
String::String(char *str){
p = str;
}
bool operator>(String &string1, String &string2){
if (strcmp(string1.p, string2.p) > 0)
return true;
else
return false;
}
int main(){
String string1("Hello"), string2("Book");
cout << (string1 > string2) << endl;
return 0;
}
运算符重载函数定义为友元函数,函数值是布尔类型。
4.6 重载单目运算符
选择带int形参的函数做前++,也可以选择不带int形参的函数做前++。
#include <iostream>
using namespace std;
class Time
{
public:
Time(){
hour = 0;
minute = 0;
sec = 0;
}
Time(int h, int m, int s) : hour(h), minute(m), sec(s) {}
Time operator++();
Time operator++(int);
void display() { cout << hour << ":" << minute << ":" << sec << endl; }
private:
int hour;
int minute;
int sec;
};
Time Time ::operator++() {// 前置单目运算符重载函数
sec++;
if (sec >= 60){
sec = sec - 60;
minute++;
if (minute >= 60){
minute = minute - 60;
hour++;
hour = hour % 24;
}
}
return *this;
}
Time Time::operator++(int){
Time temp(*this); // 保存修改前的对象做返回值
++(*this);
return temp;
}
int main()
{
Time time1(21, 34, 59), time2;
cout << " time1 : ";
time1.display();
++time1;
cout << "++time1: ";
time1.display();
time2 = time1++;
cout << "time1++: ";
time1.display();
cout << " time2 : ";
time2.display();
return 0;
}
运行结果:
time1 : 21:34:59
++time1: 21:35:0
time1++: 21:35:1
time2 : 21:35:0
4.7 重载流插入运算符和流提取运算符
用户自定义类型的数据不能直接用<<和>>输出和输入,如想用它们进行输入或输出,必须对它们重载。
ostream &operator<<(ostream &output, Complex &c)
{
output << "(" << c.real << "+" << c.imag << "i)" << endl;
return output;
}
/////
Complex c1(2, 4), c2(6, 10), c3;
c3 = c1 + c2;
cout << c3;
用cin>>输入复数,用cout<<输出复数。
istream &operator>>(istream &input, Complex &c)
{
cout << " 请输入复数的实部和虚部:";
input >> c.real >> c.imag;
return input;
}