红皮书(P122-P132)
——————————终于进入了第四章 2016.3.24
运算符的重载
一、为什么要进行运算符的重载?
为了实现多种定义方式的公用符号但是也不至于发生错误。
例子:“+”重载,计算复数加
#include <iostream>
using namespace std;
class Complex
{
public:
Complex( ){ real = 0; imge = 0; }
Complex(double , double );
Complex Complex_add(Complex &c);//注意:返回值类型是Complex类型的。
void display();
private:
double real;
double imge;
};
Complex::Complex(double r, double i)
{
real = r;
imge = i;
}
Complex Complex :: Complex_add(Complex & cc)
{
Complex c;
c.real = real + cc.real;
//相当于c.real = this->real + c1.real;
//这个this指针指向的当前调用这个成员函数的对象,
//对于下面的实例来说是c1
c.imge = imge + cc.imge;
return c;
}
void Complex::display()
{
cout << real << "+" << imge << "i" << endl;
}
int main()
{
Complex c1(2, 5);
Complex c2(2.5, 6.5);
Complex c3;
c3=c1.Complex_add(c2);
c3.display();
system("pause");
return 0;
}
这个方法是单纯地用了加号的重载来实现的。不像我们之前看到的那样,直接写加号就支持运算。
如果我们想方便的计算,利用通用的形式即:
c3=c1+c2;
怎么实现?
答:运算符的重载!
故思议就是重载运算符的。本质是:函数的重载。
一般格式:
函数类型 operator 运算符名称 (形参表)
{对运算符的重载处理}
例,对加法的重载:
Complex operator + (Complex & c1,Complex &c2);
对上面的代码进行改变:
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(){ real = 0; imge = 0; }
Complex(double, double);
//*******************运算符的重载声明************************************
Complex operator +(Complex & ); //运算符的重载
//*************************************************************************
//这样做只是为了很直观,重载了+,这样可以直接运用+而不用用自定义的函数
void display();
private:
double real;
double imge;
};
Complex::Complex(double r, double i)
{
real = r;
imge = i;
}
//————————————————不同之处————————————————————————
Complex Complex::operator+(Complex& cc)
{
Complex c;
c.real = real + cc.real; //相当于c.real = this->real + c1.real;
//这个this指针指向的当前调用这个成员函数的对象,对于下面的实例来说是c1
//(所以它其实是两个参数,一个是隐藏的参数tihs指针指着的是第一个参数,括号里面引用的是第二个参数)
c.imge = imge + cc.imge;
return c;
}
//———————————————————————————————————————————————
void Complex::display()
{
cout << real << "+" << imge << "i" << endl;
}
int main()
{
Complex c1(2, 5);
Complex c2(2.5, 6.5);
Complex c3;
c3 = c1+c2; //完整的是c3=c1.operator(c2);
c3.display();
system("pause");
return 0;
}
运算符重载是为了方便。这样用户就不用考虑它怎么实现的,而只要放心的用就行了。
重载规则:
1、不允许定义新的运算符:运算符额重载是重载,所以不允许定义新的运算符,定义了就不叫重载
2、不能重载的运算符: . * :: sizeof ?:
3、重载不能改变运算符所支持的运算对象的个数:一目只能重载成一目,双目只能重载成双目。
4、重载不改变运算符的优先级
5、重载不改变运算符的结合性。
6、重载运算符不能有默认的参数:有了固定的参数则就不叫重载了,只是自己新定义的函数而已,失去了重载的意义。
7、重载的函数必须和用户定义的类对象一起使用,其参数至少是一个类对象。例:
int operator +(int a,int b)
{ return (a-b); }
这样是错的。
Complex operator + (int a ,Complex b)
{ return Complex ( a+c.real , c.imag ) }
这样是允许的。
8、类对象的运算符一般必须重载,=和&不必重载
运算符重载作为类成员函数和友元函数
1、上面的第二个程序是作为类的成员函数的。
2、重载声明为外部函数,但是将其定义成友元函数实现操作:
重载函数作为友元函数实现功能:(部分代码)
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(){ real = 0; imge = 0; }
Complex(double, double);
//*******************运算符重载成友元函数************************************
friend Complex operator +(Complex & c1, Complex & c2); //运算符的重载
//*************************************************************************
void display();
private:
double real;
double imge;
};
//————————————————不同之处————————————————————————
Complex operator+(Complex & c1, Complex & c2)
{
Complex c;
c.real = c1.real + c2.real;//这时候两个变量必须显示的指出来,因为友元函数没有this指针
c.imge = c1.imge + c2.imge;
return c;
}
代码二:说明的是重载类型可以不一样:
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(){ real = 0; imge = 0; }
Complex(double, double);
//*******************运算符重载成友元函数************************************
friend Complex operator +(Complex & c1, Complex & c2); //运算符的重载
friend Complex operator+(int c1, Complex & c2);
//*************************************************************************
void display();
private:
double real;
double imge;
};
//————————————————不同之处————————————————————————
Complex::Complex(double r, double i)
{
real = r;
imge = i;
}
//————————————————一个操作对象是int 另一个是类对象—————————————————————
Complex operator+(int c1, Complex & c2)//必须两个参数
{
//但是声明以及运用的时候的顺序不能变如果是第一个参数是int则第一个操作数必须是int类型。
return Complex(c1 + c2.real, c2.imge);
}
//———————————————————————————————————————————————
void Complex::display()
{
cout << real << "+" << imge << "i" << endl;
}
int main()
{
int c1=2;
Complex c2(2.5, 6.5);
Complex c3;
c3 = c1 + c2;//第一个参数是int类型
c3.display();
system("pause");
return 0;
}
一般将双目声明成友元函数,其余的声明成类的成员函数。
后记:今天写了很多了,明天继续介绍,还有两三次就结束这一章了,好几天没自己动手写代码了,今天写下。