打印本文 打印本文  关闭窗口 关闭窗口  
二级C++多态性:运算符重载中的两种形式
作者:佚名  文章来源:不详  点击数  更新时间:2008/4/18 14:40:14  文章录入:杜斌  责任编辑:杜斌

1•  重载为类的成员函数:

格式: < 类名 > operator < 运算符 >(< 参数表 >)

例如:利用重载运算符实现复数类对象的算术四则运算。

#include <iostream.h>

class complex

{

public:

complex(){ real=imag=0;}

complex(double r,double I)

{

real=r;imag=I;

}

complex operator +(complex &c);

complex operator -(complex &c);

complex operator *(complex &c);

complex operator /(complex &c);

friend void print(complex &c);

private:

double real,imag;

};

inline complex complex::operator +(complex &c)

{

return complex(real+c.real,imag+c.imag);

}

inline complex complex::operator –(complex &c)

{

return complex(real-c.real,imag-c.imag);

}

inline complex complex::operator *(complex &c)

{

return complex(real*c.real-imag*c.imag,real*c.imag+imag*c.real);

}

inline complex complex::operator /(complex &c)

{

return complex((real*c.real+imag*c.imag)/(c.real*c.real+c.imag*c.imag),

(imag*c.real-real*c.imag)/(c.real*c.real+c.imag*c.imag));

}

void print(complex &c)

{

if(c.imag<0)

cout<<c.real<<”-“<<c.imag<<”i”;

else

cout<<c.real<<”+”<<c.imag<<”i”;

}

void main()

{

complex c1(2.0,3.0),c2(4.0,-2.0),c3;

c3=c1+c2;

cout<<”\nc1+c2=”;

print(c3);

c3=c1-c2;

cout<<”\nc1-c2=”;

print(c3);

c3=c1*c2;

cout<<”\nc1*c2=”;

print(c3);

c3=c1/c2;

cout<<”\nc1/c2=”;

print(c3);

c3=(c1+c2)*(c1-c2)*c2/c1;

cout<<”\n(c1+c2)*(c1-c2)*c2/c 1” ;

print(c3);

cout<<endl;

说明:①程序中的表达式: c1+c2 ,编译程序将解释 c1.operator+(c2)

   ②当重载成为成员函数时,双目运算符仅有一个参数。对单目运算符,重载为成员函数时,总是隐含了一个 参数,该参数是 this 指针。 This 指针指向调用该成员函数对象的指针。

2、重载为友员函数:

  当重载友员函数时,将没有隐含的参数 this 指针。这样,对双目运算符,友员函数有2个参数,对单目运算符,友员函数有一个参数。

格式: friend < 类型说明符 >operaotr < 运算符 >(< 参数表 >)

{……..}

例如:重写上例:

#include <iostream.h>

class complex

{

public:

complex (){real=imag=0;}

complex(double r,double I)

{

real=r;imag=I;

}

friend complex operator +(complex &c1,complex &c2);

friend complex operator -(complex &c1,complex &c2);

friend complex operator *(complex &c1,complex &c2);

friend complex operator /(complex &c1,complex &c2);

friend void print(complex &c);

private:

double real,imag;

};

complex operator +(complex &c1,complex &c2)

{

return complex(c1real+c2.real,c1.imag+c2.imag);

}

complex operator –(complex &c1,complex &c2)

{

return complex(c1.real-c2.real,c1.imag-c2.imag);

}

complex operator *(complex &c1,complex &c2)

{

return complex(c1real*c2.real-c1.imag*c2.imag,c1.real*c2.imag+c1.imag*c2.real);

}

complex operator /(complex &c1,complex &c2)

{

return complex((c1.real*c2.real+c1.imag*c2.imag)/(c1.real*c2.real+c1.imag*c2.imag),

(c1.imag*c2.real-c1.real*c2.imag)/(c1.real*c2.real+c1.imag*c2.imag));

}

void print(complex &c)

{

if(c.imag<0)

cout<<c.real<<”-“<<c.imag<<”i”;

else

cout<<c.real<<”+”<<c.imag<<”i”;

}

void main()

{

complex c1(2.0,3.0),c2(4.0,-2.0),c3;

c3=c1+c2;

cout<<”\nc1+c2=”;

print(c3);

c3=c1-c2;

cout<<”\nc1-c2=”;

print(c3);

c3=c1*c2;

cout<<”\nc1*c2=”;

print(c3);

c3=c1/c2;

cout<<”\nc1/c2=”;

print(c3);

c3=(c1+c2)*(c1-c2)*c2/c1;

cout<<”\n(c1+c2)*(c1-c2)*c2/c 1” ;

print(c3);

cout<<endl;

说明: c1+c2 编译程序结实为 operator+(c1,c2), 将调用 complex operator +(complex &c1,complex &c2) 求值。

同理, c1-c2 理解为 operator –(c1,c2), 调用 complex operator –(complex &c1,complex &c2) 实现上述表达式的求值。

3 、两种重载形式的比较:

  一般来说,单目运算符最好被重载为成员函数,对双目运算符最好被重载为友员函数。

  例如: c+5.67

  其中 c 是 complex 类的对象,上述表达式表明复数加上一个浮点数,这是有意义的。其结果是将浮点数加到复数的实部,虚部不变。

  重载为成员函数:

→ c.operator+(5.67)

→ c.operator+(complex(5.67))

重载为友员:

→ operator+(c,5.67)

→ operator+(c,complex(5.67))

可行。 

再考虑: 5.67+c

    重载为友元: operator+(complex(5.67),c)

  重载为成员函数: 5.67.operator+(c),j 就不对了。

  所以,对双目运算符重载为友员函数比重载为成员函数更方便写。但是有的双目运算符还是重载为成员函数,如赋值运算符。

例如:将赋值运算符重载为成员函数:

#include <iostream.h>

class A

{

public:

A(){X=Y=0;}

A(int I,int j){X=I;Y=j;}

A(A&p)

{

X.p.X;Y=p.Y;

}

A&operator=(A &p);

Int getX(){ return X;}

Int getY()

{ return Y;}

private:

int X,Y;

}

A&A::operator=(A&p)

{

X=p.X;

Y=p.Y;

Cout<<”ssignment operator called.\n”;

Return *this;

}

void main()

{

A a(7,8);

A b;

B=a;

Cout<<b.getX()<<”,”<<b.getY()<<endl;

}

执行结果: Assignment operator called.

7,8

说明: b=a, 解释为: b.operator=(a), 调用: A&A::operator=(A &p)

例如:重载增1减1运算符。

Obj++ 或 obj—

#include <iostream.h>

class counter

{

public:

counter(){v=0;}

counter operator ++();

counter operator ++(int);

void print(){cout<<v<<endl;}

private:

unsigned v;

};

counter counter::operator ++()

{

v++;

return *this;

}

counter counter::operator ++(int)

{

counter t;

t.v=v++;

return t;

}

void main()

{

counter c;

for (int I=0;I<8;I++)

c++;

c.print();

for(I=0;I<8;I++)

++c;

c.print();

}

执行结果:8

     16

说明:重载运算函数 counter operator ++() 为前缀运算符; counter operator ++(int) 为后缀运算符。

4 、插入符(<< )和提取符 (>>) 的重载。

例如:重载插入符和提取符对日期进行输出和输入。

#include <iostream.h>

class Date

{

public:

Date(int y,int m,int d)

{ Year=y;Month=m;Day=d;}

friend ostream &operator<<(ostream &stream,Date &date);

friend istream &operator >>(istream &stream,Date &date);

private:

int Year,Month,Day;

};

ostream &operator <<(ostream &stream &stream,Date &date)

{

srteam<<date.Year<<”/”<<date.Month<<”/”<<date.Day<<endl;

return stream;

}

istream &operator >>(istream &stream ,Date &date)

{

stream>>date.Year>>date.Month>>date.Day;

return stream;

}

void main()

{

Date Cdate(1998,8,17);

Cout<<”Current date:”<<Cdate<<endl;

Cout<<”Enter new date:”;

Cin>>Cdate;

Cout<<”New date:”<<Cdate<<endl;

}

执行: current date: 1998/8/17

Enter new date:1998 8 18

New date: 1998/8/18

分析:定义重载插入符时,使用 ostream 类,因为 cout 是从该类中派生出来的。定义重载提取符时,使用 istream 类,因为 cin 是从该类中派生出来的。重载的运算符函数 说明为类的友员函数,目的是为访问类中的私有成员。

例如:对于复数这种数据类型 的插入符和提取符进行重载。

#include <iostream.h>

class complex

{

public:

complex(){real=imag=0.0;}

complex(double a,double b)

{ real=a;imag=b;}

friend complex operator +(complex &c1,complex &c2);

friend ostream &operator <<(ostream &stre,complex &c);

friend istream &operator>>(istream &stre,complex &c);

private:

double real,imag;

} ;

complex operator+(complex &c1,complex &c2)

{

double r=c1.real+c2.real;

double I=c1.imag+c2.imag;

return complex (r,I);

}

osrteam &operator<<(ostream&stre,complex &c)

{

stre<<”(“<<c.real<<”,”<<c.imag<<”)”;

return stre;

}

istream&operator>>(istream &stre,complex &c)

{

stre>>c.real>>c.imag;

return stre;

}

void main()

{

complex x,y,z;

cout<<”Input two complex number:\n”;

cin>>x>>y;

z=x+y;

cout<<z<<endl;

}

执行: Input two complex number:

5 9 23 46

(28,55)

打印本文 打印本文  关闭窗口 关闭窗口