运算符的重载方法

以程序实例分数类--Fraction来说明运算符的重载方法。

1  // 运算符重载——Fraction

  2  //Fraction.h

  3  #ifndef FRACTION_H

  4  #define FRACTION_H

  5  #include<iostream>

  6  using std::istream;

  7  using std::ostream;

  8 

  9  class Fraction

 10  {   

 11        friend istream& operator>>(istream&,Fraction&);//全局函数重载>>

 12       friend ostream& operator<<(ostream&,const Fraction&);//全局函数重载<<

 13       friend Fraction operator!(const Fraction&);//全局函数重载一元运算符

 14     //全局函数重载二元运算符

 15       friend Fraction operator+(const Fraction&,const Fraction&);

 16       friend Fraction& operator++(Fraction&);//全局函数重载前缀++运算符

 17       friend Fraction operator++(Fraction&,int);//全局函数重载后缀++运算符

 18  public:

 19       Fraction(int=0,int=1);//默认构造函数

 20       Fraction(double);//根据double构造Fraction     

 21       void set(int,int);

 22       Fraction operator-()const;//成员函数重载一元运算符

 23       Fraction operator-(const Fraction&)const;//成员函数重载二元运算符

 24       operator double()const;//类型转换

 25       Fraction operator--();//成员函数重载前缀--算符

 26       Fraction operator--(int);//成员函数重载后缀--算符

 27  private:

 28       int molecular;//分子

 29       int denominator;//分母

 30       static int gcd(int,int);//求两个整数的最大公约数

 31  };

 32  #endif

 33 

 34  //Fraction.cpp

 35  #include "Fraction.h"

 36  #include<cmath>

 37 

 38  //求两个整数的最大公约数

 39  int Fraction::gcd(int a,int b)

 40  {

 41       while(b)

 42       {

 43              int t=a;

 44              a=b;

 45              b=t%b;

 46       }

 47       return a;

 48  }

 49  //默认构造函数

 50  Fraction::Fraction(int m,int d)

 51  {

 52       set(m,d);

 53  }

 54  //根据double构造Fraction

 55  Fraction::Fraction(double db)

 56  {

 57       int m=0;

 58       int d=1;

 59       const double precision=0.000001;

 60       double tmp=fabs(db);

 61       while(1)

 62       {

 63              if(m*1.0/d>tmp)

 64                     ++d;

 65              if(m*1.0/d<tmp)

 66                     ++m;

 67              if(fabs(m*1.0/d-tmp)<precision) break;

 68       }

 69       if(db<0)

 70              m=-m;

 71       molecular=m;

 72       denominator=d;

 73  }   

 74  void Fraction::set(int m,int d)

 75  {

 76       if(d==0)

 77              d=1;

 78       int t=gcd(m,d);

 79       molecular=m/t;

 80       denominator=d/t;

 81  }

 82  //成员函数重载一元运算符

 83  Fraction Fraction::operator-()const

 84  {

 85       return Fraction(-molecular,denominator);

 86  }

 87  //成员函数重载二元运算符

 88  Fraction Fraction::operator-(const Fraction& other)const

 89  {

 90       int m=other.denominator*molecular-denominator*other.molecular;

 91       int d=denominator*other.denominator;

 92       return Fraction(m,d);

 93  }

 94  //类型转换

 95  Fraction::operator double()const

 96  {

 97       return molecular*1.0/denominator;

 98  }

 99  //成员函数重载前缀--算符

100  Fraction Fraction::operator--()

101  {

102       molecular-=denominator;

103       return *this;

104  }

105  //成员函数重载后缀--算符

106  Fraction Fraction::operator--(int)

107  {

108       Fraction tmp=*this;

109       molecular-=denominator;

110        return tmp;

111  }

112 

113  //全局函数重载>>

114  istream& operator>>(istream& in,Fraction& fraction)

115  {

116        int m=0;

117        int d=1;

118        in>>m;

119        in.ignore();

120       in>>d;

121       fraction.set(m,d);

122       return in;

123  }

124  //全局函数重载<<

125  ostream& operator<<(ostream& out,const Fraction& fraction)

126  {

127       if(double(fraction)<0)

128              out<<"-";

129       out<<fabs(fraction.molecular);

130       if(fraction.molecular!=0&&fraction.denominator!=1)

131              out<<"/"<<fabs(fraction.denominator);

132       return out;

133  }

134  //全局函数重载一元运算符

135  Fraction operator!(const Fraction& fraction)

136  {

137       Fraction tmp;

138       tmp.set(fraction.denominator,fraction.molecular);

139       return tmp;

140  }

141  //全局函数重载二元运算符

142  Fraction operator+(const Fraction& fraction1,const Fraction& fraction2)

143  {

144       int m=fraction2.denominator*fraction1.molecular+

145                fraction1.denominator*fraction2.molecular;

146       int d=fraction1.denominator*fraction2.denominator;

147       return Fraction(m,d);

148  }

149  //全局函数重载前缀++运算符

150  Fraction& operator++(Fraction& fraction)

151  {

152       fraction.molecular+=fraction.denominator;

153       return fraction;

154  }

155  //全局函数重载后缀++运算符

156  Fraction operator++(Fraction& fraction,int)

157  {   

158       Fraction tmp=fraction;

159       fraction.molecular+=fraction.denominator;

160     return tmp;

161  }

162  //test.cpp

163  #include<iostream>

164  #include"Fraction.h"

165  using std::cin;

166  using std::cout;

167  using std::endl;

168 

169  int main()

170  {

171     //测试默认构造函数

172       Fraction a;

173       cout<<"a="<<a<<endl;

174       //根据double构造Fraction的构造函数

175       Fraction b(0.333333);

176       cout<<"b="<<b<<endl;

177       //测试setgcd函数

178       a.set(-25,35);

179       cout<<"a.set(-25,35)之后"<<endl;

180       cout<<"a="<<a<<endl;

181       //测试成员函数重载的一元运算符-

182       cout<<"-a="<<a.operator -()<<endl;

183       cout<<"-a="<<-a<<endl;

184       //测试成员函数重载的二元运算符-

185       cout<<"a-b="<<a.operator -(b)<<endl;

186       cout<<"a-b="<<a-b<<endl;

187       //测试全局函数重载的一元运算符!

188       cout<<"a的倒数="<<operator!(a)<<endl;

189       cout<<"a的倒数="<<!a<<endl;

190       //测试全局函数重载的二元运算符+

191       cout<<"a+b="<<operator +(a,b)<<endl;

192       cout<<"a+b="<<a+b<<endl;

193       //测试流提取运算符>>

194       cout<<"输入一个分数,分子和分母使用一个字符分隔"<<endl;

195       cin>>a;

196       cout<<"a="<<a<<endl;

197       //测试类型转换double

198       double d1=a;//隐式转换

199       double d2=static_cast<double>(a);//显式转换

200       cout<<"d1="<<d1<<endl;

201       cout<<"d2="<<d2<<endl;

202       //测试全局函数重载的前缀++和后缀++

203       cout<<"b=++a之前"<<endl;

204       cout<<"a="<<a<<endl;

205       cout<<"b="<<b<<endl;

206       b=++a;

207       cout<<"b=++a之后"<<endl;

208       cout<<"a="<<a<<endl;

209       cout<<"b="<<b<<endl;

210       cout<<"b=a++之前"<<endl;

211        cout<<"a="<<a<<endl;

212       cout<<"b="<<b<<endl;

213       b=a++;

214     cout<<"b=a++之后"<<endl;

215       cout<<"a="<<a<<endl;

216       cout<<"b="<<b<<endl; 

217       cout<<"++++a="<<++++a<<endl;

218       //测试成员函数重载的前缀--和后缀--

219       cout<<"b=--a之前"<<endl;

220       cout<<"a="<<a<<endl;

221       cout<<"b="<<b<<endl;

222       cout<<"b=--a之后"<<endl;

223       b=--a;

224       cout<<"a="<<a<<endl;

225       cout<<"b="<<b<<endl;

226       cout<<"b=a--之前"<<endl;

227       cout<<"a="<<a<<endl;

228       cout<<"b="<<b<<endl;

229       b=a--;

230       cout<<"b=a--之后"<<endl;

231       cout<<"a="<<a<<endl;

232       cout<<"b="<<b<<endl; 

233       cout<<"----a="<<----a<<endl;

234 

235       return 0;

236  }

显示结果:

a=0

b=1/3

a.set(-25,35)之后

a=-5/7

-a=5/7

-a=5/7

a-b=-22/21

a-b=-22/21

a的倒数=-7/5

a的倒数=-7/5

a+b=-8/21

a+b=-8/21

输入一个分数,分子和分母使用一个字符分隔

10/20

a=1/2

d1=0.5

d2=0.5

b=++a之前

a=1/2

b=1/3

b=++a之后

a=3/2

b=3/2

b=a++之前

a=3/2

b=3/2

b=a++之后

a=5/2

b=3/2

++++a=9/2

b=--a之前

a=9/2

b=3/2

b=--a之后

a=7/2

b=7/2

b=a--之前

a=7/2

b=7/2

b=a--之后

a=5/2

b=7/2

----a=1/2

在第30行声明,第38~48行实现的static成员函数gcd可以返回两个int型数据的最大公约数,该函数与类型Fraction无关,可以作为全局函数实现。但是本例中仅在类型Fraction定义的内部使用该函数,因此将其作为Fraction类的private成员函数,并且由于该函数没有访问任何成员变量,所以又将该函数声明为static成员。

在第19行声明,第49~53行实现的构造函数有2int型参数,分别用于初始成员变量moleculardenominator,函数体中调用另一个成员函数set完成赋值功能。该函数的2个参数均有默认值,所以它是Fraction类的默认构造函数。该构造函数调用时,可以仅提供1int型参数,因此,它具有int型到Fraction类型的转换功能

在第20行声明,第54~73行实现的构造函数有1double型参数,并使用这个double型数据构造Fraction类对象,函数体中采用逐步试探的方法来确定分子和分母(当然也可以采用效率更高的算法)。该函数是单参数的构造函数,因此,它具有double型到Fraction类型的转换功能

在第21行声明,第74~81行实现的成员函数set负责通过2int型参数设置一个Fraction类型对象的成员变量moleculardenominator。为了简便起见,函数体中对于第2个参数为0的情况只做了简单的纠正,没有提示错误或抛出异常等。同时,本函数调用函数gcd求出2个参数的最大公约数,并使用约分后的数值分别为成员变量moleculardenominator赋值。

main函数中对以上函数做了简单的测试(第169~236行)。

 

展开阅读全文

没有更多推荐了,返回首页