![]() ![]() |
|
二级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) |
|
![]() ![]() |