以程序实例分数类--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 //测试set和gcd函数
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行实现的构造函数有2个int型参数,分别用于初始成员变量molecular和denominator,函数体中调用另一个成员函数set完成赋值功能。该函数的2个参数均有默认值,所以它是Fraction类的默认构造函数。该构造函数调用时,可以仅提供1个int型参数,因此,它具有int型到Fraction类型的转换功能。
在第20行声明,第54~73行实现的构造函数有1个double型参数,并使用这个double型数据构造Fraction类对象,函数体中采用逐步试探的方法来确定分子和分母(当然也可以采用效率更高的算法)。该函数是单参数的构造函数,因此,它具有double型到Fraction类型的转换功能。
在第21行声明,第74~81行实现的成员函数set负责通过2个int型参数设置一个Fraction类型对象的成员变量molecular和denominator。为了简便起见,函数体中对于第2个参数为0的情况只做了简单的纠正,没有提示错误或抛出异常等。同时,本函数调用函数gcd求出2个参数的最大公约数,并使用约分后的数值分别为成员变量molecular和denominator赋值。
main函数中对以上函数做了简单的测试(第169~236行)。