操作符重载-1,成员函数(含this)
(Operator Overloading)
inline complex&
_doapl(complex* ths, const complex& r)//do assignment plus(doapl)
{ //右边复数r的实部加到左边复数ths的实部上
ths ->re += r.re;
ths ->im += r.im;
}
inline complex&
//将操作符 += 重载
//所有的成员函数都带有一个隐藏的参数,即使下一行括号中无this,但它也在
//complex::operator += (this, const complex& r)
//代码的参数列中不能写出这里的this
//这里的this就是指c2,this是指针所以编译器会把c2的地址传进去
complex::operator += (const complex& r)
{
return _doapl(this, r);
}
应用
{ //新建2个复数
complex c1(2,1);
complex c2(5);
//c2=c2+c1
c2 += c1;
}
操作符重载-2,非成员函数(无this)
例1:
inline complex
operator + (const complex& x, const complex& y)// +操作符的重载
{
return complex(real(x) + real(y)),
imag(x) + imag(y) );
}
inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + y, imag (x));
}
inline complex
operator + (double x, const complex& y)
{
return complex(x + real(y), imag(y));
}
应用
{
complex c1(2,1);
complex c2;
//inline complex operator + (const complex& x, const complex& y)
c2 = c1 + c2;//复数+复数
//inline complex operator + (const complex& x, double y)
c2 = c1 + 5;//复数c2为c1实部+5,c2的虚部为c1虚部
//inline complex operator + (double x, const complex& y)
c2 = 7 + c1;//复数c2为7+c1的实部,c2的虚部为c1的虚部
}
例2:
inline bool
operator == (const complex& x,const complex& y)// ==操作符的重载
{
return real(x) == real(y) && imag(x) == imag(y);
}
inline bool
operator == (const complex& x, double y)
{
return real(x) == y && imag(x) == 0;
}
inline bool
operator == (double x, const complex& y)
{
return x == real(y) && imag(y) ==0;
}
应用
{
complex c1(2,1);
complex c2;
//inline bool operator == (const complex& x,const complex& y)
cout << (c1 == c2);
//inline bool operator == (const complex& x, double y)
cout << (c1 == 2);
//inline bool operator == (double x, const complex& y)
cout << (0 == c2);
}
例3:
inline complex
conj (const complex& x)//共轭复数,全局函数(global)
{
return complex (real(x), -imag(x));
}
#include <iostream.h>
ostream& //返回类型为引用类型
operator << (ostream& os, const complex& x)// <<操作符的重载,全局函数
{ //返回的不是local变量,所以返回类型可以使用引用类型
return os << '(' << real(x) << ','
<< imag(x) << ')';
}
应用
{
complex c1(2,1);
//ostream& operator << (ostream& os, const complex& x)
//第一个参数cout传递到ostream& os
cout << conj(c1); //(2,-1)
cout << c1 << conj(c1); //(2,1) (2,-1)
}
Note:
设计一个函数有两种想法
1.设计为成员函数
2.设计为全局函数
Return by reference 语法分析
传递者(例子中指c1)无需知道接收端(doapl函数的参数部分)是用什么形式接收,这就是传递引用的好处
inline complex&//声明返回引用
_doapl(complex* ths, const complex& r)//传进来的左侧参数是一个指针
{
...
//返回指针所指的东西,是value,接收端是接收什么不必在乎(上面声明接收引用)
return *ths;
}
inline complex&
complex::operator += (const complex& r)
{
return _doapl(this,r);
}
应用
{
complex c1(2,1);
complex c2(5);
//c1为传递者,接收者参数部分的complex& r
c2 += c1;//执行函数inline complex& complex::operator +=(const complex& r){...}
//c1先加到c2上的结果再加到c3上
c3 += c2 += c1;
}
Class body之外的各种定义
inline double
imag(const complex& x)//imag前没有class字样,所以该函数为全局函数
{ //参数通过引用来传递,比传值效率高
return x.imag();
}
inline double
real(const complex& x)
{
return x.real();
}
应用
{
complex c1(2,1);
//取得复数c1的虚部和实部
cout << imag(c1);
cout << real(c1);
}
Temp object(临时对象) typename();
inline complex //优先考虑返回值类型为引用,这里complex为什么没有使用引用类型,因为他们返回的必定是个local object
operator + (const complex& x, const complex& y)
{ //这里实部加实部的结果(存在临时对象中)将值传递出去后自动死亡,所以这个结果(指下面两实(虚)部相加的结果)(这个结果会存到临时对象中),所以声明返回值类型不能为引用类型
//复数是在函数complex中创建的
return complex (real(x) + real(y)),
imag(x) + imag(y) );
}
inline complex
operator + (const complex& x, double y)
{ //complex为类名称typename();
return complex (real(x) + y, imag (x));
}
inline complex
operator + (double x, const complex& y)
{
return complex (x + real(y), imag(y));
}
应用
{
int(7);
complex c1(2,1);
complex c2;
//typename();创建临时对象,参数为默认值
complex();
//typename();创建临时对象,参数为4,5
complex(4,5);
//以上创建的两个临时对象,在程序运行到本行时结束
cout << complex(2);
}
Class body之外的各种定义
//取正
inline complex
operator + (const complex& x)//只有一个参数表面+含义为正号而不是加法
{
return x;
}
//negate反相(取反)
inline complex
operator - (const complex& x)//这种函数绝对不可return by reference,因为其返回的必定是个local object
{ //对实部和虚部都取反
return complex (-real(x), -imag(x));
}
应用
{
complex c1(2,1);
complex c2;
cout << -c1;//将复数c1取反
cout << +c1;//将复数c1取正
}